Home > Software design >  How to write unit test case for componentDidMount() and export default connect(null, updateProps)(&l
How to write unit test case for componentDidMount() and export default connect(null, updateProps)(&l

Time:12-06

I have created simple react component and write test cases of components that are working correctly. I have got coverage report for the test cases.

Now, I have added react redux in my other component. this component contains componentDidMount() and export default connect(null, updateProps)(ComponentName) methods. I need to write unit test cases for these methods.

Please refer to the below code sample,

class MyComponent extends Component {
       componentDidMount = () => {
          //some code here
      )

      handleSignIn = (e) => {
          //some code here
      }

      render() {
        return (
          <div>
             <form  onSubmit={this.handleSignIn}>
               <Input
                 type="text"
                 name="inputText"
                 placeholder="Text"
                 autoFocus
                 required
               />
            </form>
        </div>
      );
    }

    const updateProps = (dispatch) => {
      return {
        //some code here
      };
    };

    export default connect(null, updateProps)(MyComponent);

CodePudding user response:

In your code you have two things:

class MyComponent

and

const thisIsBasicallyAnotherComponent = connect(null, updateProps)(MyComponent);

So if you want to test your component you basically have two options. You can test your component wrapped and connected to the redux store or you can write a simple unit test for your class component as it is.

What I would recommend doing is to export your class component

- class MyComponent extends Component { // replace this
  export class MyComponent extends Component { // with this

And then you can test your React component with Jest like any other component.

test('Link changes the class when hovered', () => {
  const component = renderer.create(
    <MyComponent {...mockProps} /> // !! keep in mind that you have to manually pass what you have in `updateProps` because the component is not connected to Redux store anymore
  );

  // ... write your test and expectations here
});

Otherwise, you can test your connected component (what is exported by default) but then you would have to wrap the component in Redux provider in order to test it.

You can find more information about testing here:

CodePudding user response:

You can use Provider from react-redux or redux-mock-store to avoid need to use real reducer:

import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import MyComponent from './MyComponent.jsx';

const mockStore = configureStore([thunk]);

it('does something on mount', () => {
  // let's mock some Redux state
  const store = mockStore({ slice1: { id: 2, name: '11' } });
  mount(<Provider store={store}><MyComponent /></Provider>);
  expect(store.getActions()).toContainEqual({
    type: 'some-type',
    payload: ....
  });
});

But this is that easy only to simple actions. What if you use redux-thunk and there is some loading? There are 2 ways:

  1. Pass redux-thunk middleware to mockStore and mock network, say, by using mock-fetch or nock. Easier to set up, but also it might be overkill if you already test your Redux directly, repeating tests for "loading failed", "loading takes long" etc also to your component would mean double work.
  2. You can mock ../yourPath/actions.js so every action there would be plain object, not a thunk. I typically go this way.

But what about "exporting unwrapped component so we could test component in isolation, without Redux"? You see, it was working when connect was the only possible API. But now with hooks like useSelector, useDispatch, useStore in mind, it's way more reliable to make tests for "my component IN Redux" first. Otherwise with "double exports" approach we may find out than converting component from class to function means way more work on patching tests, not on component itself.

  • Related