Angular2 Jasmine SpyOn方法不存在

时间:2017-02-22 20:28:18

标签: angular jasmine

我已经定义了一个接口和不透明令牌,如下所示

export let AUTH_SERVICE = new OpaqueToken('auth.service');

export interface AuthService {
    logIn(): void;
    logOut(): void;
}

在我的测试类中,我提供了AuthService的存根版本,即

@Injectable()
class AuthServiceStub implements AuthService {
    logIn(): void {}
    logOut(): void {}
}

并设置我的测试beforeEach,如下所示

beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [ LoginComponent ],
            providers: [
                {provide: AUTH_SERVICE, useValue: AuthServiceStub}
            ]
        });
    }));

然后我开始编写测试,即

it('should call log in on AuthService', () => {
        let authService = fixture.debugElement.injector.get(AUTH_SERVICE);
        spyOn(authService, 'logIn');
        // expect will go here
});

但是我收到以下错误

 Error: <spyOn> : logIn() method does not exist

看不出我做错了什么。有什么想法吗?

1 个答案:

答案 0 :(得分:15)

那是因为你在提供者对象中使用了useValue属性。这意味着注入的值将是AuthServiceStub类本身。你想要的是它实际拥有这些方法的实例。

要使测试有效,请将useValue替换为useClass。这将使Angular的依赖注入系统在创建提供程序时实际实例化服务,并且您的调用fixture.debugElement.injector.get(AUTH_SERVICE);将返回正确的对象。

或者,您可以手动实例化该类:

it('should call log in on AuthService', () => {
    let AuthService = fixture.debugElement.injector.get(AUTH_SERVICE);
    let authService = new AuthService();
    spyOn(authService, 'logIn');
    // expect will go here
});

尽管如此,useClass是一个更好的解决方案,因为它可以处理AuthService可能需要的所有未来注入。