I am learning taking this testing course to test connected components by setting up a store factory
test helper that 'creates a store for testing that matches the configuration of our store'. Below, you can see my connected sample component as well as the code used to setup tests, in which I create a connected, shallow enzyme wrapper of my sample component. However, it seems like the initial state I am passing to the sample component, in this case {jotto: 'foo'}
is not getting passed to my sample component when creating this shallow wrapper. Am I doing something wrong and how can I correctly recreate the necessary store configuration when running enzyme tests? Thanks!
Sample Component:
import React from 'react';
import {connect} from 'react-redux';
const SampleComponent = (props) => {
console.log(props);
return (
<div>This is a sample component!</div>
);
};
const mapStateToProps = (state) => ({
jotto: state.jotto,
});
export default connect(mapStateToProps)(SampleComponent);
reducer:
import * as jottoActionTypes from 'actionTypes/jottoActionTypes';
export const initialState = {
isSuccess: false,
};
const jotto = (state = initialState, action) => {
switch (action.type) {
case jottoActionTypes.CORRECT_GUESS:
return {
...state,
isSuccess: true,
};
default:
return state;
}
};
export default jotto;
root reducer:
import {combineReducers} from 'redux';
import {connectRouter} from 'connected-react-router';
import jotto from 'reducers/jottoReducer';
export default (historyObject) => combineReducers({
jotto,
router: connectRouter(historyObject),
});
Setting up test:
import React from 'react';
import {shallow} from 'enzyme';
import {createStore} from 'redux';
import rootReducer from 'reducers/rootReducer';
import SampleComponent from './sampleComponent';
export const storeFactory = (initialState) => createStore(rootReducer, initialState);
const store = storeFactory({jotto: 'foo'});
const wrapper = shallow(<SampleComponent store={store} />).dive();
console.log(wrapper.debug());
// Result:
{ store:
{ dispatch: [Function: dispatch],
subscribe: [Function: subscribe],
getState: [Function: getState],
replaceReducer: [Function: replaceReducer],
[Symbol(observable)]: [Function: observable] },
jotto: undefined,
dispatch: [Function: dispatch],
storeSubscription:
Subscription {
store:
{ dispatch: [Function: dispatch],
subscribe: [Function: subscribe],
getState: [Function: getState],
replaceReducer: [Function: replaceReducer],
[Symbol(observable)]: [Function: observable] },
parentSub: undefined,
onStateChange: [Function: bound onStateChange],
unsubscribe: [Function: unsubscribe],
listeners:
{ clear: [Function: clear],
notify: [Function: notify],
get: [Function: get],
subscribe: [Function: subscribe] } } }
Just a heads up about that Udemy course... it's not the greatest learning tool. The instructor approaches testing using
data attributes
which are unnecessary forjest
andenzyme
testing (they also crowd up theDOM
with unused attributes).In addition, her code experience is around a beginner level and she makes quite a few mistakes and odd code choices. That said, learn what you can from it and start looking into tests created by those who maintain popular npm packages (most well-documented and popular packages will contain tests that'll teach you a more practical approach of
unit
andintegration
testing).Anyway, I digress, you have two options for testing a
container
:export
theclass
/pure function
,shallow
ormount
wrap it, and update it with fake props (very easy, less of a headache, and more common to do)<Provider>
and react-router-dom's<MemoryRouter>
, and thenmount
it (can become very complex as it requires a semi-deep understanding of: enzyme and how it interprets the DOM when a component is mounted, redux's action/reducer flow, how to create mock implementations and/or mock files, and how to properly handlepromise
based actions).Working examples (click the
Tests
tab to run the tests; locate the.tests.js
in the directories mentioned below):Note: Codesandbox currently has some testing limitations as noted below, so please adjust for your local project.
containers/Dashboard/__tests__/UnconnectedDashboard.test.js (you can just as easily
mount
wrap this unconnected component to assert against its deeply nested children nodes)containers/Dashboard/__tests__/ConnectedDashboard.test.js
Solution: I forgot the browser parameter for my root reducer, given I was using
connected-react-router
.