Redux测试 - ReferenceError:未定义localStorage [英] Redux Testing - ReferenceError: localStorage is not defined

查看:87
本文介绍了Redux测试 - ReferenceError:未定义localStorage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在我的redux操作上运行测试时遇到很多麻烦。测试通过,但每次运行时都会出现以下错误:

I'm currently having a lot of trouble running tests on my redux actions. The test passes but I get the following error each time it is ran:

ReferenceError: localStorage is not defined

之前我也遇到了错误:

ReferenceError: fetch is not defined

我通过使用isomorphic-fetch修复此问题。无论如何,我不确定如何配置Mocha来运行这些前端测试。任何帮助将非常感激。

I fixed this by using isomorphic-fetch. Anyway I am unsure on how I should configure Mocha to run these front end tests. Any help would be much appreciated.

摩卡测试命令:

mocha -w test/test_helper.js test/*.spec.js






test_helper.js:

require('babel-register')();
var jsdom = require('jsdom').jsdom;

var exposedProperties = ['window', 'navigator', 'document'];

global.document = jsdom('');
global.window = document.defaultView;

Object.keys(document.defaultView).forEach((property) => {
  if (typeof global[property] === 'undefined') {
    exposedProperties.push(property);
    global[property] = document.defaultView[property];
  }
});

global.navigator = {
  userAgent: 'node.js'
};

documentRef = document;






auth.actions.spec.js

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as actions from '../client/app/actions/auth'
import * as types from '../client/app/constants/ActionTypes'
import nock from 'nock'
import chai from 'chai'
import sinon from 'sinon'

var expect = chai.expect

import { SERVER_API } from './config'

const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)

describe('auth actions', () => {

afterEach(() => {
    nock.cleanAll()
})

it('creates LOGIN_REQUEST and LOGINSUCCESS when correct username and password provided', () => {

    nock(SERVER_API)
    .post('/login', {
      username: 'test',
      password: 'password'
    })
    .reply(200, {
      token: 'TOKEN'
    });

    const expectedActions = [
    { 
        type: types.LOGIN_REQUEST,
        isFetching: true,
        isAuthenticated: false,
        creds: {
          username: 'test',
         password: 'password'
        } 
    },
    { 
        type: types.LOGIN_SUCCESS,
        isFetching: false,
        isAuthenticated: true,
        token: 'TOKEN'
    }
    ]

    const INITAL_STATE = {
      isFetching: false,
      isAuthenticated: false
    }
    const store = mockStore(INITAL_STATE)

    return    store.dispatch(actions.loginUser({username:'test',password:'password'}))
       .then(() => {
        expect(store.getActions()).to.deep.equal(expectedActions)
       })
    })
})






auth.js

import { push } from 'react-router-redux'
import 'es6-promise'
import fetch from 'isomorphic-fetch'

import {
  LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE
} from '../constants/ActionTypes.js'

import { SERVER_PORT } from '../constants/config'


function requestLogin(creds) {
  return {
    type: LOGIN_REQUEST,
    isFetching: true,
    isAuthenticated: false,
    creds
  }
}

function receiveLogin(user) {
  return {
    type: LOGIN_SUCCESS,
    isFetching: false,
    isAuthenticated: true,
    token: user.token
  }
}

function loginError(message) {
  return {
    type: LOGIN_FAILURE,
    isFetching: false,
    isAuthenticated: false,
    message
  }
}

export function loginUser(creds) {

  let config = {
    method: 'POST',
    headers: { 'Content-Type':'application/x-www-form-urlencoded' },
    body: `username=${creds.username}&password=${creds.password}`
  }

  return dispatch => {
    dispatch(requestLogin(creds))
    return fetch('http://localhost:'+SERVER_PORT+'/api/login', config)
      .then(response =>
        response.json()
        .then(user => ({ user, response }))
      ).then(({ user, response }) =>  {
        if (!response.ok) {
          dispatch(loginError(user.message))
          return Promise.reject(user)
        }
        else {
          dispatch(receiveLogin(user))
          localStorage.setItem('token', user.token) //offending line
          dispatch(push('foo'))
        }
      }).catch(err => console.log("Error: ", err))
  }
}






谢谢。


Thanks.

推荐答案

非常简单的错误,你不能在你的 localStorage 上使用mocha测试,因为没有定义 window.localStorage 。有两种方法可以解决这个问题。更正常的方式是从您的操作中移动 localStorage 调用,因为这是一个副作用,它是redux操作中的反模式。相反,您应该拥有捕获此操作的中间件并设置 localStorage

Pretty straightforward error, you can't use localStorage on your mocha tests because window.localStorage isn't defined. There are two ways to fix this. The more "canon" way would be to move that localStorage call from your action because this is a side-effect which is an anti-pattern in redux actions. Instead you should have middleware that catches this action and sets the localStorage.

通过这样做,您已经消除了测试此操作的问题。

By doing that, you already eliminate the issue of testing this action.

但是,如果您不知道该怎么做而且认为不明智,那么您可以伪造 localStorage 在mocha测试文件的顶部创建一个全局变量,创建一个假的 localStorage 。我建议不要使用这个,但它肯定是一个可以适用于你的情况的解决方案。

If, however, you don't know how to do that and don't think it wise, then you can "fake" localStorage by making a global variable at the top of your mocha test file which creates a fake localStorage. I recommend against this one but it's definitely a solution that could work in your case.

这篇关于Redux测试 - ReferenceError:未定义localStorage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆