Angular - 如何使用异步服务调用对测试组件进行单元化

时间:2017-10-24 15:11:56

标签: angular unit-testing

我有以下组件从Angular服务中检索数据:

MemberId | HomeStoreId | VisitedStoreId | Month | Visits | HomeStoreVisits 
   1            5               5           1       5           5
   1            5               3           1       2           5
   1            5               2           1       1           5
   1            5               4           1       7           5

然后我的单元测试:

export class MyComponent {
    constructor() {
        myService.get().then(() => {
            console.log('hello from constructor');
        });
    }
}

不幸的是,这导致以下日志:

///////////

it('does something', () => {
    console.log('hello from unit test');
});

///////////

如何在运行单元测试之前确保构造函数完成?

2 个答案:

答案 0 :(得分:3)

不要使用构造函数来加载数据,而是实现OnInit接口。

import { OnInit } from '@angular/core';
export class MyComponent implements OnInit {

    constructor(private myService: MyService) {}

    ngOnInit() {
        myService.get().then(() => {
            console.log('hello from constructor');
        });
    }
}
  • 另请参阅角度文档Lifecycle Hooks
  • 不要忘记注入您的myService实例之类的依赖项,我将其添加到构造函数中。

测试

我建议您阅读Testing documentation。这是很多信息,但值得。以下是用于对组件进行单元测试的代码。

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
}));

答案 1 :(得分:0)

您的构造函数在测试之前正在执行,但是,构造函数的代码会对服务进行异步调用,并在测试后执行。

首先,您应该考虑将该服务调用从构造函数中移除。

其次,当你为一个组件编写测试时,你通常会监视服务电话,并检查它们是否被调用,你实际上没有打电话,你就是嘲笑它。查看&#39; spyOn&#39;。

的文档

最后,如果您希望在测试之前发生某些事情,请先了解一下&#39; beforeEach&#39;。无论如何,希望这会有所帮助。