Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 203
Leon Gaban Avatar asked Jun 06 '17 20:06

Leon Gaban


People also ask

What is React used for?

React is a JavaScript library developed by Facebook which, among other things, was used to build Instagram.com. Its aim is to allow developers to easily create fast user interfaces for websites and applications alike.

Is React for HTML or js?

To get an overview of what React is, you can write React code directly in HTML. But in order to use React in production, you need npm and Node. js installed.

Is React better or Angular?

React is better than Angular due to it's virtual DOM implementation and rendering optimizations. Migrating between React's versions is quite easy, too; you don't need to install updates one by one, as in the case of Angular. Finally, with React, developers have myriads of existing solutions they can use.


2 Answers

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.

like image 113
Leon Gaban Avatar answered Sep 26 '22 04:09

Leon Gaban


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.

like image 37
Swivel Avatar answered Sep 23 '22 04:09

Swivel