【问题标题】:Mocking a service in unit tests在单元测试中模拟服务
【发布时间】:2016-04-22 19:56:49
【问题描述】:

我正在尝试为组件单元测试模拟服务。 这是我的服务:

@Injectable()
export class LoginService {

    constructor(public http: Http) { }

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

...

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

然后我尝试模拟它:

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 reject: 'expect' was used when there is no current spec,这可能是因为异步测试超时;区:;任务:Promise.then ;值:错误:在没有当前规范时使用了“期望”,这可能是因为异步测试超时(...)

我知道该服务是异步执行的,并且测试在某处丢失了。 angular2-polyfills.js:530 错误:未捕获(在承诺中):错误:在没有当前规范时使用了“期望”,这可能是因为异步测试超时(...)

我尝试了使用 tick 的 fakeAsync - 没有成功。 提前致谢!

【问题讨论】:

  • 尝试injectAsync([TestComponentBuilder], 而不是inject([TestComponentBuilder], ..

标签: angular karma-jasmine


【解决方案1】:

您可以尝试手动实例化您的模拟服务并在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.

【讨论】:

  • 明白了!我没有返回任何东西,这就是我的代码行为不端的原因。谢谢!
  • 我正在遵循这个建议,但后来我收到了一堆类似这样的错误:Argument of type 'MockUserService' is not assignable to parameter of type 'UserService'。我该如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2021-04-05
  • 1970-01-01
  • 2016-10-28
  • 2012-11-15
相关资源
最近更新 更多