如何使用Mocha / Sinon / Chai对localStorage进行单元测试

时间:2015-03-28 14:03:16

标签: unit-testing local-storage mocha sinon chai

我有2个简单的方法抽象读取和写入localStorage:

_readLocalStorage: function(key) {
    if (window.localStorage && window.localStorage.getItem(key)) {
        return JSON.parse(window.localStorage.getItem(key));
    } else {
        throw new Error('Could not read from localStorage');
    }
},

_writeLocalStorage: function(key, data) {
    try {
        window.localStorage.setItem(key, JSON.stringify(data));
    } catch (e) {
        throw new Error('Could not write to localStorage');
    }
},

显然,存根window.localStorage.getItem / setItem很简单。但是localStorage未定义的情况呢?

我尝试过缓存/取消窗口.localStorage(第二个断言):

describe('#_readLocalStorage', function() {
    it('should read from localStorage', function() {
        // set up
        var stub1 = sinon.stub(window.localStorage, 'getItem')
        .returns('{"foo": "bar"}');

        // run unit
        var result = service._readLocalStorage('foo');

        // verify expectations
        expect(result)
        .to.eql({foo: 'bar'});

        // tear down
        stub1.restore();
    });

    it('should throw an error if localStorage is undefined', function() {
        // set up
        var cachedLocalStorage = window.localStorage;
        window.localStorage = undefined;

        // run unit/verify expectations
        expect(service._readLocalStorage('foo'))
        .to.throw(new Error('Could not write to localStorage'));

        // tear down
        window.localStorage = cachedLocalStorage;
    });
});

然而,这不起作用。摩卡/柴似乎没有抓住抛出的错误。

我已经环顾四周但却找不到办法解决这个问题。

1 个答案:

答案 0 :(得分:3)

您的expect应该是

expect(service._readLocalStorage.bind(service, 'foo'))
    .to.throw(new Error('Could not write to localStorage'));

在调用 service._readLocalStorage('foo')之前,您可以通过编码调用expect 进行编码。因此它引发了expect无法处理的异常。 expect需要能够处理异常的是函数 expect 本身将调用。使用service._readLocalStorage.bind(service, 'foo')创建一个新函数,在没有参数的情况下调用(如expect所做)将等同于调用service._readLocalStorage('foo')

您的测试还有另一个问题:您的清理代码永远不会执行。断言库通过引发JavaScript异常来报告问题。因此,除非特殊处理异常,否则任何遵循失败异常的代码都不会运行。你可以这样做:

it('should throw an error if localStorage is undefined', function() {
    // set up
    var cachedLocalStorage = window.localStorage;
    window.localStorage = undefined;

    // run unit/verify expectations
    try {
        expect(...)...;
        expect(...)...;
        ...
    }
    finally {
        // tear down
        window.localStorage = cachedLocalStorage;
    }
});

对于更复杂的情况,您应该使用beforebeforeEachafterafterEach进行设置和拆解。