Jeppe Christensen
Jeppe Christensen

Reputation: 1890

Testing component with Jest which use Redux-toolkit, "Store does not have a valid reducer"

So I have been battling with this issue for some time now, and I can't seem to figure out, what I'm doing wrong here.

I'm currently in the process of testing a component, which use a Redux-store to get certain states for a user.

As is, I'm keeping individual reducers, combineReducer and Store in separate files for better structure as the project grows.

Currently I just have a very simple test, which basically lets me know if the component renders or not:

test('Component renders', () => {
    const test = shallow(<Provider store={mockStore}>
        <UserPage />
    </Provider>)
    expect(test).not.toBeNull()
})

Currently, I'm trying to work my way backwards in the process of finding out, why my test is passing with a bunch of errors:

The following works for me, (I put everyting into my testfile):

import { userObject } from "../../constants";
import { combineReducers, configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
import UserPage from './UserPage';

const initialState = {
    user: userObject,
    loadingUser: false,
};
const userSlice = createSlice({
    name: 'user',
    initialState: initialState,
    reducers: {
        setUser(state, action) {
            state.user = action.payload
        },
        setLoadingUser(state) {
            state.loadingUser = !state.loadingUser
        }
    }
})

const reducers = combineReducers({
    user: userReducer
});



const mockStore = configureStore({ reducer: reducers })

test('Component renders', () => {
    const test = shallow(<Provider store={mockStore}>
        <UserPage />
    </Provider>)
    expect(test).not.toBeNull()
})

Naturally, this is not optimal, because I want to test my real reducer - So I went ahead and did the following (As the next step in working my way backwards - understanding why it fails):

import userReducer from '../PATH/userReducer'
import { userObject } from "../../constants";


const reducers = combineReducers({
    user: userReducer
});
const mockStore = configureStore({ reducer: reducers })

test('Component renders', () => {
    const test = shallow(<Provider store={mockStore}>
        <UserPage />
    </Provider>)
    expect(test).not.toBeNull()
})

My Reducer:

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    user: userObject,
    loadingUser: false,
};


const userSlice = createSlice({
    name: 'user',
    initialState: initialState,
    reducers: {
        setUser(state, action) {
            state.user = action.payload
        },
        setLoadingUser(state) {
            state.loadingUser = !state.loadingUser
        }
    }
})

export default userSlice.reducer;

Now my test passes, but for some reason - It gives me a bunch of errors (Which eventually will make my further tests fail, because the reducer is "undefined")

console errors:

console.error
Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.

  at warning (node_modules/redux/lib/redux.js:402:13)
  at currentReducer (node_modules/redux/lib/redux.js:525:9)
  at dispatch (node_modules/redux/lib/redux.js:296:22)
  at apply (node_modules/redux/lib/redux.js:382:3)
  at node_modules/redux/lib/redux.js:658:31
  at createStore (node_modules/redux/lib/redux.js:162:12)
  at configureStore (node_modules/@reduxjs/toolkit/dist/redux-toolkit.cjs.development.js:536:12)

NOTE Hardcoding the userObject does not have an effect.

Upvotes: 1

Views: 1501

Answers (1)

phry
phry

Reputation: 44086

I would assume that your import of the userReducer is a wrong path or something similar - try to console.log it before using combineReducers to make sure it is defined and a function.

Also, as a general feedback: shallow rendering with enzyme will probably not work very well in the future (it's already pretty problematic). You might probably want to look into testing-library to be future-proof.

Upvotes: 1

Related Questions