如何伪造Jasmine离线?

问题描述 投票:1回答:1

我有一个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测试?

javascript unit-testing jasmine karma-jasmine
1个回答
2
投票

您没有机会覆盖一些内置属性。虽然使用Object.defineProperty(),您可以重新配置内置属性。

Jasmine 2.6 and newer

由于Jasmine 2.6(release notes)有spyOnProperty()

这是你如何窥探navigator.onLine

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

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

Jasmine pre 2.6

为浏览器对象构建一个外观

使用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(虽然这超出了这个答案)。

© www.soinside.com 2019 - 2024. All rights reserved.