2016-05-23 42 views
3

私は現在、私のreduxアクションでテストを実行する際に多くの問題を抱えています。テストパスが、私は次のようなエラーにそれが実行されるたびに取得:Reduxテスト - ReferenceError:localStorageが定義されていません

ReferenceError: localStorage is not defined 

私もあったの前にエラーが発生しました:

ReferenceError: fetch is not defined 

私は同型フェッチを使用してこれを修正しました。とにかく、これらのフロントエンドテストを実行するためにMochaを設定する必要があるかどうかは不明です。どんな助けでも大歓迎です。


モカテストコマンド:

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; 

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.actions.spec.js 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)) 
    } 
} 

感謝。

答えて

4

わかりやすい簡単なエラーのため、window.localStorageは定義されていないため、mochaテストではlocalStorageを使用できません。これを修正するには2つの方法があります。これは副作用であり、これは還元的な行動の反パターンであるため、あなたの行動からそのlocalStorage呼び出しを移動させることがより多くの "標準的な"方法です。代わりに、このアクションをキャッチし、localStorageを設定するミドルウェアを持っている必要があります。

このようにすることで、この操作をテストするという問題は既に解決されています。

、しかし、あなたがそれを行う方法がわからない、それは賢明とは思わない場合は、あなたが偽のlocalStorageを作成し、あなたのモカテストファイルの先頭にグローバル変数を行うことによりlocalStorage「偽」することができます。私はこれに反対することをお勧めしますが、あなたのケースではうまくいく可能性のあるソリューションです。

+0

ご返信いただきありがとうございます。これが理由だと思っていましたが、代わりにtest_helperを使ってローカルストレージを偽装することができるかどうかはわかりませんでした。間違いなくミドルウェアを試してみます。ありがとうございました。 – edcarr

+0

@ZekeDroidまた、 'localStorage'グローバル変数内に' setItem'メソッドを作成する必要があります。 – Emo

+0

他の方法の中でも、はい – ZekeDroid

関連する問題