Angular Jasmine.js测试-spy on window.navigator.userAgent
我需要找到更改Angular Jasmine.js测试-spy on window.navigator.userAgent,angular,unit-testing,jasmine,karma-jasmine,spyon,Angular,Unit Testing,Jasmine,Karma Jasmine,Spyon,我需要找到更改userAgent值的方法。我试图在窗口.navigator.userAgent中使用spyOn。但那没用 JS: @Injectable() export class DetectBrowserService { browserIE: boolean; constructor() { this.browserIE = this.detectExplorer(); } public detectExplorer() { const brows =
userAgent
值的方法。我试图在窗口.navigator.userAgent
中使用spyOn
。但那没用
JS:
@Injectable()
export class DetectBrowserService {
browserIE: boolean;
constructor() {
this.browserIE = this.detectExplorer();
}
public detectExplorer() {
const brows = window.navigator.userAgent;
const msie = brows.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return true;
}
}
}
it('should test window.navigator.userAgent', () => {
const wind = jasmine.createSpy('window.navigator.userAgent');
wind.and.returnValue('1111');
detectBrowserService = TestBed.get(DetectBrowserService);
console.log(window.navigator.userAgent);
});
规范:
@Injectable()
export class DetectBrowserService {
browserIE: boolean;
constructor() {
this.browserIE = this.detectExplorer();
}
public detectExplorer() {
const brows = window.navigator.userAgent;
const msie = brows.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return true;
}
}
}
it('should test window.navigator.userAgent', () => {
const wind = jasmine.createSpy('window.navigator.userAgent');
wind.and.returnValue('1111');
detectBrowserService = TestBed.get(DetectBrowserService);
console.log(window.navigator.userAgent);
});
我期待着
1111
,但得到了关于我的浏览器的真实信息。userAgent
是窗口的只读/常量属性。navigator
。和jasmine.createSpy
通常用于在方法而不是属性上创建间谍
现在,我尝试直接执行window.navigator.userAgent='1111'代码>作为window.navigator
可以在我的测试中访问。但我得到了一个错误,说:
[ts]无法分配给“userAgent”,因为它是常量或只读属性。
(属性)NavigatorID.userAgent:string
因此,唯一的选择是使用好的旧\uuuuuu defineGetter\uuuuuu
。这就是我在这里所做的:
it('should test window.navigator.userAgent', () => {
window.navigator['__defineGetter__']('userAgent', function(){
return '1111' // Return whatever you want here
});
detectBrowserService = TestBed.get(DetectBrowserService);
console.log(window.navigator.userAgent);
});
它的工作原理是:
希望这有帮助 我意识到这很古老,但为了进一步说明我的答案,下面是我测试safari特定行为的步骤。在测试结束时,它还会重置userAgent,以使其他测试不受影响(如注释中所要求的)
我用JasmineAPI本身得到了一个简单的解决方案
spyOnProperty(window.navigator, 'userAgent').and.returnValue('Mozilla');
根据您的要求在每个测试中修改spy
不确定此API来自哪个Jasmine版本,但v3.4支持此API
一旦发现任何全局属性,最好在每次测试后清除该属性
例如
description('Test',function(){
const NAVIGATOR=window.NAVIGATOR;
beforeach(函数(){
spyOnProperty(window.navigator,'userAgent')。和.returnValue('Mozilla');
})
之后(函数(){
window.navigator=navigator;
});
}
我建议将本机api调用封装到紧密函数(如中)中,并监视这些函数而不是本机api。依赖紧密函数可使代码更具可移植性(服务器端呈现、多浏览器问题等)而且是可测试的。我一直在用jasmine监视本机窗口api时遇到问题。为了清洁起见:在测试后有没有办法撤消此操作?这应该使用spyOnProperty
,而不是重写窗口实现。请参阅以获取正确答案。这应该标记为“正确答案”!我在过去一天一直在搜索一个有效的答案。令人尴尬的是,这太简单了,我应该早一点想到。谢谢@Subroto,这帮我搞定了。为什么需要重置导航器?spyOnProperty应该在每个测试用例后自动重置。后退一步,即使它没有重置,spyOnProperty也会更新window.navigator.userAgent和更改将随原始导航器一起进行。您应该重置window.navigator.userAgent getter。重置任何属性都很好,这样测试就不会以某些意外行为运行。如果两个测试(外部级别)需要相同的navigator
属性,但使用不同的用例,重置该属性将确保不会发生意外情况。