我正在为我的ReactJs应用程序设置Mocha(主要是ES6格式)。
在使用package.json中的"test": "mocha --compilers js:babel-register --recursive"
安装程序运行测试时,我得到以下输出:
purezen_@mb ~/workspace/webapp (Test-Setup●●)$ npm test
> webapp@0.1.0 test /Users/purezen_/workspace/webapp
> mocha --compilers js:babel-register --recursive
/Users/purezen_/workspace/webapp/src/js/data/reducers/auth.js:31
var auth = sessionStorage.getItem('auth');
^
ReferenceError: sessionStorage is not defined
at Object.<anonymous> (auth.js:5:14)
at Module._compile (module.js:397:26)
at loader (/Users/purezen_/workspace/kredx-fe/client/node_modules/babel-register/lib/node.js:158:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/purezen_/workspace/webapp/node_modules/babel-register/lib/node.js:168:7)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (index.js:5:1)
at Module._compile (module.js:397:26)
at loader (/Users/purezen_/workspace/webapp/node_modules/babel-register/lib/node.js:158:5)
测试/动作/ actions.spec.js
import configureMockStore from 'redux-mock-store'
import createSagaMiddleware from 'redux-saga'
import sagas from 'data/sagas'
import nock from 'nock'
import expect from 'expect'
(function (glob) {
function mockStorage() {
var storage = {};
return {
setItem: function(key, value) {
storage[key] = value || '';
},
getItem: function(key) {
return storage[key];
},
removeItem: function(key) {
delete storage[key];
},
get length () {
return Object.keys(storage).length;
},
key: function(i) {
var keys = Object.keys(storage);
return keys[i] || null;
}
};
}
glob.localStorage = mockStorage();
glob.sessionStorage = mockStorage();
}(typeof window !== 'undefined' ? window : global));
const sagaMiddleware = createSagaMiddleware(sagas)
const middlewares = [ sagaMiddleware ]
const mockStore = configureMockStore(middlewares)
// const storeWithMiddleware = applyMiddleware(middlewares)(mockStore)
console.log(mockStore)
我曾尝试在spec文件中实现模拟会话存储,但这似乎没什么帮助。
编辑:这是我在评论中要求的auth.js
import * as c from 'data/constants'
import {Map} from 'immutable'
// Load auth details from session storage
const auth = sessionStorage.getItem('auth');
const defaultState = Map(JSON.parse(auth));
export default function (state=defaultState, action) {
const { type, payload} = action
switch (type) {
case c.SET_AUTH: {
return Map(payload)
}
}
return state;
}
答案 0 :(得分:1)
好的,我看到了问题。您正尝试在测试中设置全局sessionStorage,这很好,但是Mocha使before
更容易。这个例子可以帮助你让事情发生变化。
这是规范应该是什么样子。
import configureMockStore from 'redux-mock-store'
import createSagaMiddleware from 'redux-saga'
import sagas from '../sagas'
import nock from 'nock'
import expect from 'expect'
describe('test the sagas', function(){
before(function(){
if(typeof window !== 'undefined') {
console.log('window is defined');
global = window;
}
function mockStorage() {
var storage = {};
return {
setItem: function(key, value) {
storage[key] = value || '';
},
getItem: function(key) {
return storage[key];
},
removeItem: function(key) {
delete storage[key];
},
get length () {
return Object.keys(storage).length;
},
key: function(i) {
var keys = Object.keys(storage);
return keys[i] || null;
}
};
}
global['localStorage'] = mockStorage();
global['sessionStorage'] = mockStorage();
});
it('should bootstrap a saga and store', function(){
const sagaMiddleware = createSagaMiddleware(sagas);
const middlewares = [ sagaMiddleware ];
const mockStore = configureMockStore(middlewares);
console.log('mockStore', mockStore);
});
});
请注意,如果不使用IIFE,我们可以使用Mocha提供的before
。这允许您在测试开始之前设置global.sessionStorage之类的东西。整个事情应该包含在describe
中,您应该使用it
来确定实际的单元测试。
在before函数中完成此引导后,对auth.js的测试可能会起作用。
我发布了此whole example to github,其他帖子中有另一个async_action示例。您可以查看并按照自述文件进行操作,这两个规格应该可行。祝好运。
答案 1 :(得分:-2)
//这应该放在mocha test folder / helpers.js
中import jsdom from 'jsdom';
// Jsdom document & window
const doc = jsdom.jsdom('<!doctype html><html><body></body><div id="react-root"></div></html>');
const win = doc.defaultView;
// Add to global
global.document = doc;
global.window = win;
global.localStorage = {};
// Add window keys to global window
Object.keys(window).forEach((key) => {
if (!(key in global)) {
global[key] = window[key];
}
});