Redux: How to test a connected component?

前端 未结 3 795
耶瑟儿~
耶瑟儿~ 2020-12-24 03:56

I am using Enzyme to unit test my React components. I understand that in order to test the raw unconnected component I\'d have to just export it and test it (I\

相关标签:
3条回答
  • 2020-12-24 04:04

    This is an interesting question.

    I usually do import both container and component to do the testing. For container testing I use, redux-mock-store. Component testing is for testing async functions. For instance in your case, login process is an async function using sinon stubs. Here is a snippet of the same,

    import React from 'react';
    import {Provider} from 'react-redux';
    import {mount, shallow} from 'enzyme';
    import {expect} from 'chai';
    import LoginContainer from '../../src/login/login.container';
    import Login from '../../src/login/Login';
    import configureMockStore from 'redux-mock-store';
    import thunk from 'redux-thunk';
    import { stub } from 'sinon';
    
    const mockStore = configureMockStore([thunk]);
    
    describe('Container Login', () => {
      let store;
      beforeEach(() => {
        store = mockStore({
          auth: {
            sport: 'BASKETBALL',
          },
        });
      });
      it('should render the container component', () => {
        const wrapper = mount(
          <Provider store={store}>
            <LoginContainer />
          </Provider>
        );
    
        expect(wrapper.find(LoginContainer).length).to.equal(1);
        const container = wrapper.find(LoginContainer);
        expect(container.find(Login).length).to.equal(1);
        expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' });
      });
    
      it('should perform login', () => {
        const loginStub = stub().withArgs({
          username: 'abcd',
          password: '1234',
        });
        const wrapper = mount(<Login
          loginUser={loginStub}
        />);
      wrapper.find('button').simulate('click');
      expect(loginStub.callCount).to.equal(1);
      });
    });
    
    0 讨论(0)
  • 2020-12-24 04:08

    As you pointed out, the way I usually do this is to export the un-connected component as well, and test that.

    i.e.

    export {Login};
    

    Here's an example. Source of the component, and source of the tests.

    For the wrapped component, I don't author tests for those because my mappings (mapStateToProps and mapDispatchToProps) are generally very simple. If I wanted to test a wrapped component, I'd really just be testing those maps. So those are what I would choose to explicitly test, rather than re-testing the entire component in a wrapped form.

    There are two ways to test those functions. One way would be to export the functions within the module itself.

    i.e.;

    export {mapStateToProps, mapDispatchToProps}

    I'm not a huge fan of this, because I wouldn't want other modules in the app to access them. In my tests, I sometimes use babel-plugin-rewire to access "in-scope" variables, so that's what I would do in this situation.

    That might look something like:

    import {
      Login, __Rewire__
    }
    
    const mapStateToProps = __Rewire__.__get__('mapStateToProps');
    
    describe('mapStateToProps', () => { ... });
    
    0 讨论(0)
  • 2020-12-24 04:14

    If we have a router issue, we can consider to add the router lib into the test file, eg:

    import React from 'react';
    import { Provider } from 'react-redux';
    import { BrowserRouter as Router } from 'react-router-dom';
    import { mount } from 'enzyme';
    import ReadDots from './ReadDots';
    
    const storeFake = state => ({
      default: () => {
      },
      subscribe: () => {
      },
      dispatch: () => {
      },
      getState: () => ({ ...state })
    });
    
    const store = storeFake({
      dot: {
        dots: [
          {
            id: '1',
            dot: 'test data',
            cost: '100',
            tag: 'pocket money'
          }
        ]
      }
    });
    
    describe('<ReadDots />', () => {
      it('should render ReadDots component', () => {
        const component = mount(
          <Provider store={store}>
            <Router>
              <ReadDots />
            </Router>
          </Provider>
        );
        expect(component.length).toEqual(1);
      });
    });
    
    0 讨论(0)
提交回复
热议问题