Nic*_*cky 3 unit-testing jasmine typescript karma-jasmine angular
我有一个使用Jasmine Testing Framework的Angular应用程序。该应用程序有一个称为的服务AuthService,用于处理JSON Web令牌的解码:
验证服务
import * as jwtDecode from 'jwt-decode';
...
@Injectable()
export class AuthService {
...
public getTokenPayload(token) {
return jwtDecode(token);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想对模块进行存根jwtDecode并为测试目的返回一个假值:
认证服务规范
...
it('should get a token payload', () => {
const fakeToken = 'fake-token';
spyOn(service, 'getTokenPayload').and.callThrough();
const tokenPayload = service.getTokenPayload(fakeToken);
expect(tokenPayload).toBe('fake-token');
});
Run Code Online (Sandbox Code Playgroud)
因为'fake-token'不是有效的JSON Web令牌,所以测试失败并显示以下消息:
InvalidTokenError: Invalid token specified: undefined is not an object (evaluating 'str.replace')
Run Code Online (Sandbox Code Playgroud)
这可能是jwt-decode模块产生的错误,这是预料之中的。我不想为了创建用于测试目的的有效JSON Web令牌而包含另一个模块。相反,我想对的功能进行存根jwtDecode()。
spyOn上jwtDecode当我使用时spyOn,我需要一个带有方法的对象。因此,对于导入的文件而言jwtDecode,这是行不通的,因为它本身是一个函数:
spyOn(jwtDecode, '<method?>').and.callFake(() => 'fake-token');
Run Code Online (Sandbox Code Playgroud)
callFake在上使用getTokenPayload我试过使用:
spyOn(service, 'getTokenPayload').and.callFake(() => 'fake-token');
Run Code Online (Sandbox Code Playgroud)
...这可以防止发生任何错误。但是,我的代码覆盖率报告现在显示该功能getTokenPayload未被覆盖。此外,我在使用外部NPM模块应用中的其他功能,我不想忽略代码覆盖率,因为他们可能需要测试的方法内其他实现。
createSpy在上使用jwtDecode我试图覆盖导入jwtDecode并创建一个间谍:
const jwtDecode = jasmine.createSpy('jwtDecode').and.returnValue('fake-token');
Run Code Online (Sandbox Code Playgroud)
这给了我与上面相同的错误,表明jwtDecode在我的实际AuthService服务中没有被覆盖。
window作为对象从这个问题,我读到全局模块可能附加到window对象。因此,我尝试对以下操作执行相同的操作jwt-decode:
在测试中...
console.log(window.jwtDecode); // undefined
console.log(window.jwt_decode); // undefined
Run Code Online (Sandbox Code Playgroud)
不幸的是,两个值都undefined在window对象上。
我想总的来说问题变成了:
如何存根导入的NPM模块?特别是,如果它们不是对象而是函数(如何在Jasmine中使用方法spyOn),则如何将它们存根?
你很亲密!由于服务只是一类,因此测试它的最佳方法是实例化一个新的服务并对其进行监视,就像您正在做的那样。如果您想监视导入的方法,则需要以某种方式将其包括在服务中。否则,您的测试将无法知道该方法是什么。
因此,请为您的服务设置属性:
jwtDecode = jwtDecode; // the imported one
Run Code Online (Sandbox Code Playgroud)
并按照this.jwtDecode您的getTokenPayload方法进行调用。
然后,以下将起作用:
const service = new AuthService( /* constructor args */ );
const jwtDecode = spyOn(service, 'jwtDecode');
jwtDecode.and.returnValue('fake-token');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
810 次 |
| 最近记录: |