2017-02-22 38 views
0

我已经如下Angular2茉莉花SpyOn方法不存在

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 

看不到我在做什么错。有任何想法吗?

+0

如果这是一个运行时错误,您可以检查您的ide或浏览器中的'authService'实例以查看是否存在'logIn'方法。 – Igor

+0

还没有让我的脑袋适当地调试这些测试。然而,如果我将一个构造函数添加到'AuthServiceStub'并写入到该构造函数的控制台中,例如'console.log('CREATED')',它从不向控制台输出'CREATED' - 所以不知道我的存根服务是否曾经得到创造.... –

回答

6

这是因为您在提供程序对象中使用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可能需要未来所有的注射。

+0

哈哈!作品....当阅读测试文档时完全通过了我。太好了,我可以继续前进:) –