angular – 在单元测试中模拟服务

我正在尝试模拟组件单元测试的服务.

我的服务:

@Injectable()
export class LoginService {

    constructor(public http: Http) { }

    getLanguages() {
        return this.http.get('the-url')
                        .map((res: Response) => res.json());
    }

注意:我的组件在构造函数中调用此方法(在构造comp时加载语言).

然后我试图嘲笑它:

class MockLoginService {
    getLanguages() {
        return Observable.of(
            [
                {
                    'name': 'English (USA)',
                    'locale': 'en-US'
                },
                {
                    'name': 'Español',
                    'locale': 'es-US'
                }
            ]
        );
    }

我的组件单元测试:

  it('should load languages', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
        tcb
            .overrideProviders(LoginComponent, [ provide(LoginService, { useClass: MockLoginService })])
            .createAsync(LoginComponent).then((fixture) => {
                let element = fixture.nativeElement;
                let loginInstance = fixture.componentInstance;
                fixture.detectChanges();
                expect(loginInstance._loginService.getLanguages).toHaveBeenCalled();
                expect(element.querySelectorAll('option').length).toBe(5);
            });
    }));

问题:

我看到我的模拟服务被调用,收到的数据是正确的,但我的2个测试被跳过了!这是日志:

angular2-polyfills.js:528 Unhandled Promise rejection: ‘expect’ was used when there was no current spec, this could be because an asynchronous test timed out ; Zone: ; Task: Promise.then ; Value: Error: ‘expect’ was used when there was no current spec, this could be because an asynchronous test timed out(…)

我承诺服务执行异步,测试在某处丢失.
angular2-polyfills.js:530错误:未捕获(在承诺中):错误:当没有当前规范时使用’expect’,这可能是因为异步测试超时(…)

我尝试使用fakeAsync并没有成功.
提前致谢 !

最佳答案 您可以尝试手动实例化您的模拟服务,并在beforeEachProviders方法回调中设置它

var service = new MockLoginService();

beforeEachProviders(() => [ provide(TestService, { useValue: service })]);

it('should load languages', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
    tcb
        .createAsync(LoginComponent).then((fixture) => {
            let element = fixture.nativeElement;
            let loginInstance = fixture.componentInstance;
            fixture.detectChanges();

            expect(element.querySelectorAll('option').length).toBe(2);
        });
}));

这个对我有用.看到这个plunkr:https://plnkr.co/edit/zTy3Ou?p=preview.

点赞