导出Redux Store无法通过酶测试

时间:2018-10-29 23:49:15

标签: reactjs react-redux jestjs enzyme

我正在使用duck patternredux-persist来建立Redux存储,如下所示:

store/index.js

/* import staments */

const persistConfig = {
  key: 'root',
  storage,
};

const ducks = {
  auth,
  password,
  navbar,
  tasks,
};

const reducer = ducksReducer(ducks);

const middleware = applyMiddleware(ducksMiddleware(reducer));

const persistedReducer = persistReducer(persistConfig, reducer);

export const store = createStore(persistedReducer, composeWithDevTools(middleware));
export const persistor = persistStore(store);

该应用程序运行正常并且所有测试都通过了,但是当我在实用工具非反应文件中导出store变量(尝试分派动作)时,测试将失败。

utils/http.js

// Commenting this line will make things work perfectly fine
import { store } from '../store'; /

import { stopSession } from '../store/modules/session';

...

const handleResponse = (response, onSuccess, onFail) => {
  if (response.status >= 200 && response.status < 300) {
    return onSuccess();
  }
  // 401 Unauthorized when session expires.
  if (response.status === 401) {
    response.text().then(message => store.dispatch(stopSession(message)));
  }
  return onFail();
};
...

所有化简器的初始状态均未定义,所有switch语句均具有默认返回值。该应用程序运行正常,只是测试不喜欢商店像这样导出和使用。

已更新:这是精简的auth减速器: 注意:不仅auth减速器损坏,每个减速器都损坏。

import http from '../../utils/http';

// Actions
export const LOGIN_RESET = 'LOGIN_RESET';
// ... more actions

// Actions creators
export const login = (email, password) => ({ type: LOGIN_REQUEST, email, password });
// ... more action creators


// Selectors
export const loginLoading = ({ auth }) => auth.loginStatus === 'loading';
export const getUser = ({ auth }) => auth.user;
// ... more selectors

const initialState = {
  loginStatus: null,
  signupStatus: null,
  signupErrors: [],
  logoutStatus: null,
  userLoggedIn: false,
  user: {},
};

export default function reduce(state = initialState, action = {}) {
  switch (action.type) {
    case LOGIN_RESET:
      return {
        ...state,
        loginStatus: null,
      };
    // ... more cases
    default:
      return state;
  }
}

// Middleware
export const middleware = ({ dispatch }) => next => async (action) => {
  next(action);
  switch (action.type) {
    case LOGIN_REQUEST: {
      const { email, password } = action;
      const response = await http.post('users/sign_in', {
        user: { email, password },
      });
      http.handleResponse(
        response,
        async () => {
          const user = await response.json();
          return dispatch({
            type: LOGIN_SUCCESS,
            user,
          });
        },
        () => dispatch({ type: LOGIN_FAILURE })
      );
      break;
    }
    // ... more cases
  return null;
};

这是正在运行的测试的屏幕截图:

Enzyme tests fail

老实说,我认为减速机或商店设置没有任何问题。当它尝试从undefined商店渲染应用程序时,这可能与酶本身有关。如果我删除http.js中的import语句,一切正常。

1 个答案:

答案 0 :(得分:0)

事实证明,商店设置或减速器没有错。我可以通过创建一个模拟http.js文件来使酶满意来解决该问题。

因此,在根级配置index.js(在__test__文件夹中)中,告诉jest从文件初始化模拟:

/* /src/__tests__/index.js */

import Adapter from 'enzyme-adapter-react-16';
import { configure } from 'enzyme';

configure({ adapter: new Adapter() });

jest.mock('../utils/http.js');

http.js文件的同一位置,添加一个模拟文件(必须位于__mocks__内)

/* /src/utils/__mocks__/http.js */

const http = {};
export default http;

问题是运行测试时,酶加载了http.js,此时尚未建立存储。也许我不应该在http助手中调度动作,一种更好的方法是使用中间件。我不确定此解决方案是否是一种好的做法,因此欢迎提出任何评论/建议。