Angular - 单元测试间谍无法识别该函数已被调用
Posted
技术标签:
【中文标题】Angular - 单元测试间谍无法识别该函数已被调用【英文标题】:Angular - unit test spy are not recognising that the function has been called 【发布时间】:2018-01-07 03:06:48 【问题描述】:我有一个用于测试指令的测试组件:
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>
【问题讨论】:
也许我是盲人,但我看不出你在哪里调用这个函数。 您是否期望.and.callThrough();
会调用该函数?
我认为他在他的 testComponents 模板中设置了 url,由于他的 setter 函数,该模板会调用它。你能确认一下吗?
@lexith 没错。我会添加它以进行澄清。
@FrankModica 每当调用 setter 时都会调用该函数。所以第一次调用图片url被指令求值。
【参考方案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()
,因为这里不需要它,无论如何都应该在测试之前调用它)
【讨论】:
它对我不起作用,因为我忘记了.and.callThrough();
! :D以上是关于Angular - 单元测试间谍无法识别该函数已被调用的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jasmine 间谍进行 Angular 2 组件测试“没有 Http 提供者!”错误