Reputation: 459
I setup react-redux-promise-listener
(repo) for react-final-form
via author instructions. Now, I'm having trouble mocking it for testing.
I'm getting error: The redux-promise-listener middleware is not installed
I've tried applying middleware within the test provider:
// app/frontend/__mocks__/TestReduxProvider.js
import React from 'react';
import { createStore, applyMiddleware } from 'redux';
import { Provider as ReduxProvider } from 'react-redux';
import { compose, setDisplayName, defaultProps } from 'recompose';
import createReduxPromiseListener from 'redux-promise-listener';
import rootReducer from '../store/rootReducer';
const displayName = 'TestReduxProvider';
const enhance = compose(
setDisplayName(displayName),
defaultProps({ state: {} }),
);
const reduxPromiseListener = createReduxPromiseListener();
function TestReduxProvider(props) {
const { state, children } = props;
const store = createStore(
rootReducer,
state,
applyMiddleware(reduxPromiseListener.middleware),
);
return <ReduxProvider store={store}>{children}</ReduxProvider>;
}
export const promiseListener = reduxPromiseListener;
export default enhance(TestReduxProvider);
// sample test
import React from 'react';
import TestReduxProvider from '~/__mocks__/TestReduxProvider';
import { render } from 'enzyme';
import Form from '../Form';
it('should not break if no params', () => {
const wrapper = render(
<TestReduxProvider>
<Form />
</TestReduxProvider>
);
expect(wrapper).toMatchSnapshot();
});
// form component relevant
import { connect } from 'react-redux';
import { Form as FormHandler } from 'react-final-form';
import MakeAsyncFunction from 'react-redux-promise-listener';
import { promiseListener } from '~/store/createStore';
import {
STATUS_SUCCESS,
STATUS_FAILURE,
} from '~/store/modules/async/constants';
const Form = props => {
const targetFormErrors = formErrors[targetAction] || '';
return (
<StyledForm >
<MakeAsyncFunction
listener={promiseListener}
start={targetAction}
resolve={`${targetAction}/${STATUS_SUCCESS}`}
reject={`${targetAction}/${STATUS_FAILURE}`}
setPayload={setPayloadHandler}
>
{asyncFunc => (
<FormHandler
onSubmit={asyncFunc}
validate={isValid}
initialValues={formattedInitialValues}
render={({ handleSubmit, pristine, errors, form }) => {
if (navigationState !== 'form') {
form.reset();
}
return (
<form
onSubmit={event => {
setSubmitAttempted(true);
handleSubmit(event)
.then(() => submitSuccessHandler(form))
.catch(() => {
});
}}
>
{inputsArray.map(formObject => {
return (
<div key={formObject.property}>
<label>
{formObject.label}
{formObject.isRequired !== false && !isDisabled && (
<span className="required"> *</span>
)}
<InputContainer>
<Input
formObject={formObject}
isDisabled={isDisabled}
/>
</InputContainer>
</label>
</div>
);
})}
</form>
);
}}
/>
)}
</MakeAsyncFunction>
</StyledForm>
);
};
export default enhance(Form);
I was expecting the snapshot to render. However, I got an error instead:
The redux-promise-listener middleware is not installed
103 | },
104 | ];
> 105 | const wrapper = render(
| ^
106 | <TestReduxProvider>
107 | <Form inputsArray={INPUTS_ARRAY} />
108 | </TestReduxProvider>
at Object.createAsyncFunction (node_modules/redux-promise-listener/dist/redux-promise-listener.cjs.js:60:13)
at new MakeAsyncFunction (node_modules/react-redux-promise-listener/dist/react-redux-promise-listener.cjs.js:82:31)
at processChild (node_modules/react-dom/cjs/react-dom-server.node.development.js:2846:14)
at resolve (node_modules/react-dom/cjs/react-dom-server.node.development.js:2812:5)
at ReactDOMServerRenderer.render (node_modules/react-dom/cjs/react-dom-server.node.development.js:3202:22)
at ReactDOMServerRenderer.read (node_modules/react-dom/cjs/react-dom-server.node.development.js:3161:29)
at Object.renderToStaticMarkup (node_modules/react-dom/cjs/react-dom-server.node.development.js:3661:27)
at Object.renderToStaticMarkup [as render] (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:742:31)
at render (node_modules/enzyme/src/render.js:21:25)
at Object.<anonymous> (app/frontend/components/views/dashboard/views/accounts/components/__tests__/Form.test.js:105:19)
Upvotes: 0
Views: 523
Reputation: 459
The issue I had with reproducing the live environment in the test environment was the promiseListener
. I ran into this issue by importing directly from store file in the component:
import { promiseListener } from '~/store/createStore';
solution:
// index.js
import createStore, { promiseListener } from './store/createStore';
import { Main } from './components';
import PromiseListenerContext from '~/store/PromiseListenerContext';
const app = (
<ReduxProvider store={appStore}>
<PromiseListenerContext.Provider value={promiseListener}>
<Main />
</PromiseListenerContext.Provider>
</ReduxProvider>
// createStore.js
import { compose, applyMiddleware, createStore } from 'redux';
import createReduxPromiseListener from 'redux-promise-listener';
const reduxPromiseListener = createReduxPromiseListener();
function createStoreWrapper(history, testMiddleware) {
const middleware = [
reduxPromiseListener.middleware,
];
if (testMiddleware) middleware.push(testMiddleware);
const enhancers = [responsiveStoreEnhancer, applyMiddleware(...middleware)];
const initialState = getInitialState();
const enhancer = compose(...enhancers);
const store = createStore(rootReducer, initialState, enhancer);
addHandlers(store);
return store;
}
export const promiseListener = reduxPromiseListener;
export default createStoreWrapper;
// test store
import React from 'react';
import { createStore, applyMiddleware } from 'redux';
import { Provider as ReduxProvider } from 'react-redux';
import { compose, setDisplayName, defaultProps } from 'recompose';
import createReduxPromiseListener from 'redux-promise-listener';
import rootReducer from '../store/rootReducer';
import PromiseListenerContext from '~/store/PromiseListenerContext';
const displayName = 'TestReduxProvider';
const enhance = compose(
setDisplayName(displayName),
defaultProps({ state: {} })
);
function TestReduxProvider(props) {
const { state, children } = props;
const reduxPromiseListener = createReduxPromiseListener();
const store = createStore(
rootReducer,
state,
applyMiddleware(reduxPromiseListener.middleware)
);
return (
<ReduxProvider store={store}>
<PromiseListenerContext.Provider value={reduxPromiseListener}>
{children}
</PromiseListenerContext.Provider>
</ReduxProvider>
);
}
// test file
import React from 'react';
import { render } from 'enzyme';
import Main from '../Main';
import TestReduxProvider from '~/__mocks__/TestReduxProvider';
it('should not break with basic params', () => {
const wrapper = render(
<TestReduxProvider>
<Main pageObject={{}} />
</TestReduxProvider>
);
expect(wrapper).toMatchSnapshot();
});
Upvotes: 1