Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shallow render with enzyme can't find elements

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?

like image 609
Jameson Avatar asked Apr 15 '18 18:04

Jameson


People also ask

What does Shallow return in Enzyme?

Shallow renders the current node and returns a shallow wrapper around it.

How can enzymes be used to be shallow?

shallow method is used to render the single component that we are testing. It does not render child components. In Enzyme version less than 3, the shallow method does not have the ability to access lifecycle methods. But in Enzyme version 3, we have this ability.

Does shallow render child components?

Shallow rendering lets you render a component “one level deep” and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM.

What is the difference between shallow and mount in Enzyme?

Always begin with shallow. If componentDidMount or componentDidUpdate should be tested, use mount. If you want to test component lifecycle and children behavior, use mount. If you want to test children rendering with less overhead than mount and you are not interested in lifecycle methods, use render.


2 Answers

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
})
like image 126
vapurrmaid Avatar answered Sep 23 '22 13:09

vapurrmaid


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()

like image 45
Januartha Avatar answered Sep 25 '22 13:09

Januartha