[英]Angular - How to unit test component with asynchronous service call
I have the following component which retrieves data from an Angular service: 我有以下组件从Angular服务检索数据:
export class MyComponent {
constructor() {
myService.get().then(() => {
console.log('hello from constructor');
});
}
}
And then my unit test: 然后我的单元测试:
///////////
it('does something', () => {
console.log('hello from unit test');
});
///////////
Unfortunately this results in the following log: 不幸的是,这导致以下日志:
> hello from unit test
> hello from constructor
How can I make sure that the constructor finishes before running the unit test? 如何在运行单元测试之前确保构造函数完成?
Do not use the constructor to load data, implement the OnInit
interface instead. 不要使用构造函数来加载数据,而是实现
OnInit
接口。
import { OnInit } from '@angular/core';
export class MyComponent implements OnInit {
constructor(private myService: MyService) {}
ngOnInit() {
myService.get().then(() => {
console.log('hello from constructor');
});
}
}
myService
instance, I added it to the constructor. myService
实例那样注入依赖项,我将它添加到构造函数中。 I recommend you read over the Testing documentation . 我建议你阅读测试文档 。 It is a lot of information but it is worth it.
这是很多信息,但值得。 Here is code that you would use to unit test your component.
以下是用于对组件进行单元测试的代码。
let comp: MyComponent ;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
providers: [
{ provide: MyService, useValue: {} }
]
})
.compileComponents();
TestBed.compileComponents();
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
}));
it('initializes the component', fakeAsync(() => {
var service = TestBed.get(MyService); // get your service
service.get = () => {
return Promise.resolve(); // you can pass data here if the service returns something
};
// here you could add an expect to validate component state before the call or service completes
comp.ngOnInit(); // call ngOnInit
tick(); // simulate the promise being resolved
expect(service.get.toHaveBeenCalled);
// here you could add an expect to validate component state after the service completes
}));
Your constructor is executing before your tests, however, your constructor's code makes an async call to a service, and that is executed after your tests. 您的构造函数在测试之前正在执行,但是,构造函数的代码会对服务进行异步调用,并在测试之后执行。
First, you should really consider moving that service call away from the constructor. 首先,您应该考虑将该服务调用从构造函数中移除。
Second, when writing tests for a component you usually spy on service calls and check that they were called, you don't actually make the call, you mock it up. 其次,当你为一个组件编写测试时,你经常监视服务调用并检查它们是否被调用,你实际上并没有进行调用,你可以模拟它。 Look up the documentation for 'spyOn'.
查找“spyOn”的文档。
Lastly, if you want something to happen before your tests, take a look at 'beforeEach'. 最后,如果您想在测试之前发生某些事情,请查看'beforeEach'。 Anyways, hope this helps.
无论如何,希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.