2017-07-19 78 views
2

我試圖寫它在其構造臨危窗口對象在它的構造角2+ UNITEST提供指令注入對象

指令代碼指令測試:

import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit } from            
    '@angular/core'; 
    import { Inject } from '@angular/core'; 
    import { Observable, Subscription } from 'rxjs/Rx'; 


    @Directive({ 
     selector: '[appFixToViewport]' 
    }) 
    export class FixToViewportDirective implements OnChanges, OnDestroy, OnInit { 
    @Input('appFixToViewport') appFixToViewport: boolean; 
    @Input('outerMargin') outerMargin: number = 15; // defaults to 15px margin 
    private windowResize$: Subscription; 

    constructor(private element: ElementRef, 
       @Inject('$window') private $window: any) {} 

    ngOnInit() { 
     this.windowResize$ = Observable.fromEvent(this.$window, 'resize') 
      .debounceTime(500) 
      .subscribe((event) => { 
       this.fixDropdownToViewPort(); 
      }); 
    } 

    ngOnChanges(changes) { 
     if (changes.appFixToViewport.currentValue) { 
      this.fixDropdownToViewPort(); 
     } 
    } 

    ngOnDestroy() { 
     if (this.windowResize$ !== undefined) { 
      this.windowResize$.unsubscribe(); 
     } 
    } 

    /** 
    * Name: fixDropdownToViewPort 
    * Purpose: put div element inside the view port 
    * Returns: void 
    */ 
    fixDropdownToViewPort() { 
     this.$window.requestAnimationFrame(() => { 
      this.element.nativeElement.style.transform = ''; // reset transform 

      let winWidth = this.$window.innerWidth; 
      // Attempt obtaining a more accurate width (excluding scrollbars) 
      if (this.$window.document && this.$window.document.body.clientWidth) { 
       winWidth = this.$window.document.body.clientWidth; 
      } 
      let elementWidth = this.element.nativeElement.offsetWidth; // div width 

      // div right border absolute position 
      let elementRight = this.element.nativeElement.getBoundingClientRect().right; 

      // div left border absolute position 
      let elementLeft = this.element.nativeElement.getBoundingClientRect().left; 

      let delta = 0; 

      if (elementRight > winWidth && winWidth > elementWidth) { // calc if the div is overflow right 
       delta = elementRight - winWidth + this.outerMargin; 
      } 
      else if (winWidth < elementWidth) { // calc if the div is bigger then the view port 
       delta = elementLeft - this.outerMargin; 
      } 
      this.element.nativeElement.style.transform = `translateX(${-delta}px)`; 
     }); 
    } 
} 

當我試圖在初始化該指令用於在模板中我收到誤注入

這裏測試組件是測試spec文件:

import {Component, ElementRef, DebugElement} from '@angular/core'; 
import {TestBed, async, ComponentFixture} from '@angular/core/testing'; 
import {FixToViewportDirective} from './fixToViewport.directive'; 
import {createInjector} from "@angular/core/src/view/refs"; 
import {By} from "@angular/platform-browser"; 


@Component({ 
    selector: 'app-test-fixtoviewport', 
    template:'<div appFixToViewport="isOpenFlag" ></div>' 
    }) 
class TestFixToViewPort {} 


describe('Directive: FixToViewportDirective',()=>{ 
    let component :TestFixToViewPort 
    let fixture : ComponentFixture<TestFixToViewPort>; 
    let inputEl: DebugElement; 
    const $window= Window; 

    beforeEach((()=>{ 

     TestBed.configureTestingModule({ 
      declarations: [ 
       TestFixToViewPort, 
       FixToViewportDirective 
      ]}); 

      fixture = TestBed.createComponent(TestFixToViewPort); 
      component= fixture.componentInstance; 
      inputEl= fixture.debugElement.query(By.css('div')); 
     })); 
    it('should have a defined component',() => { 
     expect(component).toBeDefined(); 
    }); 
    }) 

與錯誤跟蹤:

指令:FixToViewportDirective

× should have a defined component 
     Error 
      at injectionError (webpack:///~/@angular/core/@angular/core.es5.js:1232:0 <- src/test.ts:1511:86) [angular] 
      at noProviderError (webpack:///~/@angular/core/@angular/core.es5.js:1270:0 <- src/test.ts:1549:12) [angular] 
      at ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/@angular/core.es5.js:2771:0 <- src/test.ts:3050:19) [angular] 
      at ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/@angular/core.es5.js:2810:0 <- src/test.ts:3089:25) [angular] 

     Expected undefined to be defined. 
      at Object.<anonymous> (webpack:///src/app/shared/fixViewport/fixToViewportTester.component.spec.ts:42:7 <- src/test.ts:144444:27) [ProxyZone] 
      at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:80:0 <- src/test.ts:114788:39) [ProxyZone] 
      at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:105:9 <- src/test.ts:114487:34) [<root>] 

Chrome 59.0.3071 (Windows 10 0.0.0) Directive: FixToViewportDirective should have a defined component FAILED 
     Error 
      at injectionError (webpack:///~/@angular/core/@angular/core.es5.js:1232:0 <- src/test.ts:1511:86) [angular] 
      at noProviderError (webpack:///~/@angular/core/@angular/core.es5.js:1270:0 <- src/test.ts:1549:12) [angular] 
      at ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/@angular/core.es5.js:2771:0 <- src/test.ts:3050:19) [angular] 
      at ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/@angular/core.es5.js:2810:0 <- src/test.ts:3089:25) [angular] 
      at ReflectiveInjector_._getByKey (webpack:///~/@angular/core/@angular/core.es5.js:2742:0 <- src/test.ts:3021:25) [angular] 
      at ReflectiveInjector_.get (webpack:///~/@angular/core/@angular/core.es5.js:2611:0 <- src/test.ts:2890:21) [angular] 
      at DynamicTestModuleInjector.NgModuleInjector.get (webpack:///~/@angular/core/@angular/core.es5.js:3579:0 <- src/test.ts:3858:52) [angular] 
      at resolveDep (webpack:///~/@angular/core/@angular/core.es5.js:11040:0 <- src/test.ts:11319:45) [angular] 
      at createClass (webpack:///~/@angular/core/@angular/core.es5.js:10896:0 <- src/test.ts:11175:91) [angular] 
      at createDirectiveInstance (webpack:///~/@angular/core/@angular/core.es5.js:10724:0 <- src/test.ts:11003:37) [angular] 
      at createViewNodes (webpack:///~/@angular/core/@angular/core.es5.js:12087:29 <- src/test.ts:12366:49) [angular] 
      at callViewAction (webpack:///~/@angular/core/@angular/core.es5.js:12531:0 <- src/test.ts:12810:13) [angular] 
      at execComponentViewsAction (webpack:///~/@angular/core/@angular/core.es5.js:12440:0 <- src/test.ts:12719:13) [angular] 
      at createViewNodes (webpack:///~/@angular/core/@angular/core.es5.js:12114:0 <- src/test.ts:12393:5) [angular] 
     Expected undefined to be defined. 
      at Object.<anonymous> (webpack:///src/app/shared/fixViewport/fixToViewportTester.component.spec.ts:42:7 <- src/test.ts:144444:27) [ProxyZone] 
      at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:80:0 <- src/test.ts:114788:39) [ProxyZone] 
      at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:105:9 <- src/test.ts:114487:34) [<root>] 

Chrome 59.0.3071 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (1.053 secs/0.076 secs) 

我如何注入到指令它搜索窗口對象?

+0

看一看這個朋友:https://stackoverflow.com/questions/36432407/how-to-unit-test-a-directive-in -angular-2 – SrAxi

+0

我意識到這個解釋,並且實際上遵循了它,然後遇到了我無法解決的這個注入問題,這個解釋並沒有涉及指令在其構造函數中具有注入的情況。 –

回答

0

嘗試增加ElementRef您的測試模塊:

TestBed.configureTestingModule({ 
      declarations: [ 
       TestFixToViewPort, 
       FixToViewportDirective 
      ], 
      imports: [ ElementRef ] 
}); 
+0

我試圖按照您的建議導入ElementRef並運行測試導致以下錯誤: 指令:FixToViewportDirective ×應該有一個定義的組件 錯誤:由模塊'DynamicTestModule'導入的意外值'ElementRef'。請添加@NgModule註釋。 at syntaxError .... –