React & Jest, how to test changing state and checking for another component

87,968

Solution 1

Figured it out! Did not need React Test Utilities

it('should render the Notification component if state.error is true', () => {
    const loginComponent = shallow(<Login />);
    loginComponent.setState({ error: true });
    expect(loginComponent.find(Notification).length).toBe(1);
});

This will set the state of error to true in the Login component, then check if the Login component contains the Notification component.

Solution 2

This should probably be refactored a bit. The Notification component should probably be always rendered in a more global component (like a Page Wrapper or some sort of other container), and it should probably render null unless there's errors within a global reducer. A Login component probably shouldn't maintain the responsibility and business logic regarding notifications.

Share:
87,968
Leon Gaban
Author by

Leon Gaban

Investor, Powerlifter, Crypto investor and global citizen You can also find me here: @leongaban | github | panga.ventures

Updated on August 08, 2020

Comments

  • Leon Gaban
    Leon Gaban over 3 years

    React - Test Utilities Docs

    I have a Login component which will display a Notification component if this.state.error is true.

    I'm now writing a Jest test to test this.

    import React from 'react'
    import ReactTestUtils from 'react-dom/test-utils';
    import { shallow } from 'enzyme'
    import toJson from 'enzyme-to-json'
    import Login from './Login'
    import Notification from '../common/Notification'
    
    describe('<Login /> component', () => {
        it('should render', () => {
            const loginComponent = shallow(<Login />);
            const tree = toJson(loginComponent);
            expect(tree).toMatchSnapshot();
        });
    
        it('should contains the words "Forgot Password"', () => {
            const loginComponent = shallow(<Login />);
            expect(loginComponent.contains('Forgot Password')).toBe(true);
        });
    
        // This test fails
        it('should render the Notification component if state.error is true', () => {
            const loginComponent = ReactTestUtils.renderIntoDocument(
                <Login />
            );
    
            const notificationComponent = ReactTestUtils.renderIntoDocument(
                <Notification />
            );
    
            loginComponent.setState({
                error: true
            }, expect(ReactTestUtils.isDOMComponent(notificationComponent)).toBe(true));
        });
    });
    

    However currently the test is failing, and I'm not sure why

    enter image description here

    In the last part of my code I've also tried this to no avail

    loginComponent.setState({
            error: true
        }, expect(ReactTestUtils. isElement(notificationComponent)).toBe(true));
    

    https://facebook.github.io/react/docs/test-utils.html

    The render() of my Login component

    render() {
        const usernameError = this.state.username.error;
        const error = this.state.error;
        const errorMsg = this.state.errorMsg;
    
        return (
            <div className="app-bg">
                { error &&
                    <Notification message={ errorMsg } closeMsg={ this.closeMessage }/>
                }
                <section id="auth-section">
                    <header>
                        <img src="static/imgs/logo.png"/>
                        <h1>tagline</h1>
                    </header>
    

    Also tried this method for testing for the Notification component after setting state.error to true

    it('should render the Notification component if state.error is true', () => {
        const loginComponent = ReactTestUtils.renderIntoDocument(
            <Login />
        );
    
        const notificationComponent = ReactTestUtils.renderIntoDocument(
            <Notification />
        );
    
        // loginComponent.setState({
        //  error: true
        // }, expect(ReactTestUtils.isDOMComponent(notificationComponent)).toBe(true));
    
        const checkForNotification = () => {
            const login = shallow(<Login />);
            expect(login.find(Notification).length).toBe(1);
        };
    
        loginComponent.setState({
            error: true
        }, checkForNotification());
    });
    

    But that test also failed.

    Also tried const login = mount(<Login />);


    Anyone else running into a problem using Jest and the React Test Utilities?