如何伪造Jasmine离线? [英] How to fake being offline in Jasmine?

查看:160
本文介绍了如何伪造Jasmine离线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个javascript函数,它应该在脱机时表现不同,而不是在线作为安全措施。我希望有一个Jasmine单元测试,可以在离线和在线模式下测试功能 - 例如,

I have a javascript function which is supposed to behave differently when offline than online as a safeguard. I would like to have a Jasmine unit test which tests the function in both offline and online modes - e.g.,

// 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的值。在之前的中,我也尝试过:

However, I am unable to fake the value of navigator.onLine. In my before, I also tried:

navigator = {
  'onLine': false
}

这也不起作用。为了彻底,我尝试了上面与 window.navigator.onLine 相同的技术,但这也没有用。

This didn't work either. To be thorough, I tried the same techniques above with window.navigator.onLine and that also didn't work.

有没有人知道如何模拟离线进行Jasmine测试?

Does anyone know how to mock being offline for a Jasmine test?

推荐答案

您无法覆盖某些内置属性。虽然使用 对象。 defineProperty() 您可以重新配置内置属性。

You have no chance to overwrite some built in properties. Though with Object.defineProperty() you can reconfigure builtin properties.

自Jasmine 2.6(发行说明 )有 spyOnProperty()

Since Jasmine 2.6 (release notes) there is spyOnProperty().

这就是你如何监视 navigator.onLine

beforeEach(function(){
    spyOnProperty(Navigator.prototype, 'isOnline').and.returnValue(false);
});

请注意原型对象 Navigator 被引用,不是它的实例 window.navigator

Note that the prototype object Navigator is referenced, not it's instance window.navigator.

使用pre Jasmine 2.6,你无法直接监视属性(或属性)。

With pre Jasmine 2.6 you can't spy attributes (or properties) directly.

我建议使用getter方法为这样的浏览器内置创建一个外观。然后你可以在你的测试中模拟那些方法来返回你喜欢的东西。

I'd suggest to create a facade for such browser builtins using getter methods. Then you can mock those methods in your tests to return what you like.

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() 和< a href =https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor =nofollow noreferrer> 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(虽然这超出了这个答案)。

You could even implement your own spyOnProperty() backport if you're desperate (that's beyond this answer though).

这篇关于如何伪造Jasmine离线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆