reactjsreact-reduxkarma-jasmineenzymeredux-mock-store

redux unit testing Store.dispatch()


i have a basic react component like this.

import React from 'react';
import store from 'src/home/store';
class PageLoading extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: this.props.message
        };
    }

    componentDidMount(){
        store.dispatch({ type: 'SET_NOTIFICATION_DIALOG', status: '200', message: this.state.message, model: 'LOADING' });
    }

    render(){
        return(<div />);
    }
}


export default PageLoading;

how to unit this component ..?

i am using karma with ezyme. i have written this below code but this is not working

import configureMockStore from 'redux-mock-store';
import PageLoading from 'src/home/components/PageLoading';

const middlewares = [];
const mockStore = configureMockStore(middlewares);

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

describe("Page Loading",()=>{
    it("testing shoul dispatch action on calling componentdid mount",()=>{
        const initialState = {}
        const store = mockStore(initialState)
        const wrapper = mount(<PageLoading message="loading"/>);
         const actions = store.getActions();
        const expectedPayload = {type: 'SET_NOTIFICATION_DIALOG', status: '200', message:"loading", model: 'LOADING' };
         expect(actions).toEqual([expectedPayload])
    })
})

i think it is not getting the store.


Solution

  • First, you should provide the store at the top of your app heirarchy.

    Use connect to connect to the store and inject dispatch in your component props:

    import React from 'react';
    import { connect } from 'react-redux';
    
    class PageLoading extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                message: this.props.message
            };
        }
    
        componentDidMount(){
            this.props.dispatch({ type: 'SET_NOTIFICATION_DIALOG', status: '200', message: this.state.message, model: 'LOADING' });
        }
    
        render(){
            return(<div />);
        }
    }
    
    export default connect()(PageLoading);
    

    In your test, you can substitute the store for the connected component by passing it as a prop:

    describe("Page Loading",()=>{
        it("testing shoul dispatch action on calling componentdid mount",()=>{
            const initialState = {}
            const store = mockStore(initialState)
            const wrapper = mount(<PageLoading store={store} message="loading"/>);
             const actions = store.getActions();
            const expectedPayload = {type: 'SET_NOTIFICATION_DIALOG', status: '200', message:"loading", model: 'LOADING' };
             expect(actions).toEqual([expectedPayload])
        })
    })