我有一个javascript函数,它应该在离线时表现不同,而不是在线作为安全措施。我想进行Jasmine单元测试,测试离线和在线模式下的功能 - 例如,
// offline
describe('When there is no connection to the internet', function() {
beforeEach(function(){
spyOn(navigator, 'onLine').and.returnValue(false);
});
it('offline behavior happens', function() {
myFunction();
expect(something).not.toHaveBeenCalled();
});
});
// online
describe('When there is a connection to the internet', function() {
beforeEach(function(){
spyOn(navigator, 'onLine').and.returnValue(true);
});
it('online behavior happens', function() {
myFunction();
expect(something).toHaveBeenCalled();
});
});
但是,我无法伪造navigator.onLine
的价值。在我的before
,我也尝试过:
navigator = {
'onLine': false
}
这也不起作用。为了彻底,我尝试了与window.navigator.onLine
相同的技术,但也没有用。
有谁知道如何模拟离线进行Jasmine测试?
您没有机会覆盖一些内置属性。虽然使用Object.defineProperty()
,您可以重新配置内置属性。
由于Jasmine 2.6(release notes)有spyOnProperty()
。
这是你如何窥探navigator.onLine
:
beforeEach(function(){
spyOnProperty(Navigator.prototype, 'onLine').and.returnValue(false);
});
请注意,引用原型对象Navigator
,而不是它的实例window.navigator
。
使用pre Jasmine 2.6,您无法直接监视属性(或属性)。
我建议使用getter方法为这样的浏览器内置创建一个外观。然后,您可以在测试中模拟这些方法以返回您喜欢的内容。
const Browser = (function() {
return {
isOnline: function() {
return navigator.onLine;
}
};
})();
在你的代码中:
if (Browser.isOnline()) {
// ...
}
在你的测试中:
beforeEach(function(){
spyOn(Browser, 'isOnline').and.returnValue(false);
});
spyOnProperty()
自己做的事情如果由于某种原因你不能从2.6之前的版本升级,你甚至可以通过使用Object.defineProperty()
和Object.getOwnPropertyDescriptor()
手动间谍。
var onlineState,
origOnLineProp;
beforeEach(function() {
// Remember original config
origOnLineProp = Object.getOwnPropertyDescriptor(Navigator.prototype, "onLine");
onlineState = true;
// New behavior
Object.defineProperty(Navigator.prototype, "onLine", {
enumerable: origOnLineProp.enumerable,
configurable: origOnLineProp.configurable,
get: function() { return onlineState }
});
});
it("...", function() {
onlineState = false;
expect("code").toBe("correctly functioning in offline mode");
});
afterEach(function() {
// Restore original behavior
Object.defineProperty(Navigator.prototype, "onLine", {
enumerable: origOnLineProp.enumerable,
configurable: origOnLineProp.configurable,
get: origOnLineProp.get
});
});
如果你绝望的话,你甚至可以实现你自己的spyOnProperty()
backport(虽然这超出了这个答案)。