6
votes

I am trying to unit test one of my React components, but the Enzyme's shallow render method is saying it cannot find elements in the component. The component renders different navigation links depending on an authentication prop.

Nav component:

    class Header extends Component {

      renderLoginNav() {
        switch(this.props.auth) {
            case null:
                return;
            case false:
                return (
                    <li key={ 1 }><a className="nav-link" href="/auth/google" 
                     id="google">Login</a></li>
                );
            default: 
                return [
                    <li key={ 2 } className="nav-item">
                        <a className="nav-link" href="/lists">Dashboard</a></li>,
                    <li key={ 3 } className="nav-item">
                        <a className="nav-link" href="/credits">Credits</a></li>,
                    <li key={ 4 } className="nav-item">
                        <a className="nav-link" href="/api/logout">Logout</a></li>
                ];
        }
    }
    render() {
        return (
                <nav>
                    <ul>
                        {this.renderLoginNav()}
                    </ul>
                </nav>
        );
    }
}
function mapStateToProps(state) {
    return {
        auth: state.auth
    }
}
export default connect(mapStateToProps)(Header);

Enzyme Test:

import React from 'react';
import { shallow, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import configureStore from 'redux-mock-store';
import Header from './';

configure({ adapter: new Adapter() });
const middlewares = [];
const mockStore = configureStore(middlewares);
it('displays correct nav when authenticated', () => {
        const initialState = { auth: {} };
        const store = mockStore(initialState);
        const wrapper = shallow(<Header store={store} />);

        expect(wrapper.find('.nav-link').length).toBe(3);
    })

When this test runs, it fails saying "expected 0 to be 3". Am I misunderstand how the shallow render method works? Or is there a flaw in how my test is setup?

2
Shallow render doesn't render the whole tree. Just one level deep. You can export the Header component and import as named import in the test case import {Header} from './';Hardik Modha
typically when using shallow for functional unit testing on a connected component, you export the component and test it without the store. You can mock any props you'd receive from the storevapurrmaid
Ah, I did not know that. ThanksJameson

2 Answers

3
votes

Nav Component:

// export the component without connecting it
export class Header extends React.Component {
  ...
}

export default connect(mapStateToProps)(Header)

Testing:

import { Header} from '../Header' // pull off unconnected component

it('displays correct nav when authenticated', () => {
  // see how we mock the props received by the store
  let wrapper = shallow(
    <Header
      auth={{}}
    />
  )
  expect(wrapper.find('.nav-item')).toHaveLength(3) // jest syntax
})
3
votes

For redux connected component you must use .dive() when using shallow

const wrapper = shallow(<Header store={store} />).dive();

Please read this post: Testing a Redux-connected component using Enzyme issue and ShallowWrapper .dive()