0

我已经得到了我使用的测试指令测试组件:角 - 单元测试谍没有认可该功能被称为

export class UnitTestComponent implements OnInit { 
    @ViewChild(BackgroundLoadedDirective) backgroundLoaded: BackgroundLoadedDirective; 

    public url = 'https://www.codeproject.com/KB/GDI-plus/ImageProcessing2/flip.jpg'; 

    constructor() {} 

    ngOnInit() {} 

    loaded(): void { 
    console.log(true) 
    } 
} 

然后,我有这个指令,我希望写一些用于测试:

@Directive({ 
    selector: '[backgroundLoaded]' 
}) 

export class BackgroundLoadedDirective { 
    @Input('backgroundLoaded') set url(value) { 
    this.createImage(value); 
    }; 

    get url() { 
    return this._url; 
    } 

    @Output() loaded: EventEmitter<any> = new EventEmitter<any>(); 

    public img: HTMLImageElement; 

    private _url: string; 

    @HostBinding('class.background-loaded') 
    isLoaded = false; 

    createImage(url: string): void { 

    // This gets logged as expected 
    console.log(url); 

    this._url = url; 

    this.img = new Image(); 

    this.img.onload =() => { 
     this.isLoaded = true; 
     this.load.emit(url); 
    }; 

    this.img.src = url; 
    } 
} 

然后我到目前为止只是这个测试:

describe('BackgroundLoadedDirective',() => { 

    let component: UnitTestComponent; 
    let fixture: ComponentFixture<UnitTestComponent>; 
    let spy: any; 

    beforeEach(() => { 

    TestBed.configureTestingModule({ 
     declarations: [ 
     UnitTestComponent, 
     BackgroundLoadedDirective 
     ], 
     schemas: [NO_ERRORS_SCHEMA], 
     providers: [ 
     {provide: ComponentFixtureAutoDetect, useValue: true} 
     ] 
    }); 

    fixture = TestBed.createComponent(UnitTestComponent); 
    component = fixture.componentInstance; 
    }); 

    it('should create a fake img tag',() => { 

    spy = spyOn(component.backgroundLoaded, 'createImage').and.callThrough(); 

    expect(component.backgroundLoaded.img).toBeTruthy(); 
    expect(spy).toHaveBeenCalled(); 
    }); 
}); 

的问题是,测试失败说:

Expected spy createImage to have been called. 

尽管函数被调用,为什么不是间谍工作?

编辑:

只是为了澄清,这是测试组件的HTML它适用的指令,并赋予它的URL。

<div [urlToBackground]="url" [backgroundLoaded]="url" (loaded)="loaded($event)"></div> 
+0

也许我是盲人,但我不明白,你调用这个函数。 – lexith

+0

你期待'.and.callThrough();'会调用函数吗? –

+0

我认为他在他的testComponents模板中设置了url,因为他的setter函数会调用它。你能证实这一点吗? – lexith

回答

1

基本上什么是干扰angulars生命周期挂钩。就时间而言,您的测试只是不够在意。

为了更容易测试,触发更改,然后测试您的setter是否工作(并调用您正在执行的功能)。

事情是这样的:

it('should create a fake img tag',() => { 
    let spy: jasmine.Spy = spyOn(component.backgroundLoaded, 'createImage').and.callThrough(); 

    comp.backgroundLoaded.url = 'foobar'; 
    fixture.detectChanges(); // wait for the change detection to kick in 

    expect(spy).toHaveBeenCalled(); 
}); 

希望它能帮助。

(编辑:除去ngOnInit一个detectChanges(),因为它不是这里所需要,并应在测试前反正叫)