运行mocha会出现错误' ReferenceError:sessionStorage未定义'

时间:2016-05-09 13:37:17

标签: javascript mocha redux session-storage

我正在为我的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;
}

2 个答案:

答案 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];
}
});