Redux: How to test a connected component?

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', () => { ... });

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);
  });
});