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?
Shallow renders the current node and returns a shallow wrapper around it.
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.
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.
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.
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
})
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With