如何使用 Mocha/Sinon/Chai 对未定义的 localStorage 进行单元测试
How do I unit test localStorage being undefined with 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 未定义的情况呢?
我试过caching/unhinging window.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;
});
});
但这不起作用。 Mocha/Chai 似乎没有捕捉到抛出的错误。
我环顾四周,但找不到任何方法来处理这个问题。
你的 expect
应该是
expect(service._readLocalStorage.bind(service, 'foo'))
.to.throw(new Error('Could not write to localStorage'));
在调用 expect
之前代码调用 service._readLocalStorage('foo')
的方式。所以它引发了 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;
}
});
对于更复杂的情况,您应该使用 before
、beforeEach
、after
、afterEach
进行设置和拆卸。
我有 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 未定义的情况呢?
我试过caching/unhinging window.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;
});
});
但这不起作用。 Mocha/Chai 似乎没有捕捉到抛出的错误。
我环顾四周,但找不到任何方法来处理这个问题。
你的 expect
应该是
expect(service._readLocalStorage.bind(service, 'foo'))
.to.throw(new Error('Could not write to localStorage'));
在调用 expect
之前代码调用 service._readLocalStorage('foo')
的方式。所以它引发了 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;
}
});
对于更复杂的情况,您应该使用 before
、beforeEach
、after
、afterEach
进行设置和拆卸。