loading...

React Jest Testing Help

kyletozer profile image Kyle Tozer ・1 min read

Hi everyone,

At the moment I am trying to test a method on a React component that contains some async logic. The method is called on a child component but it method on the child also calls a method on a parent (A Context API Provider). The method on the parent returns a promise, however the method does not resolve in the child. Is there a way I can get this method to complete in my Jest test? Am I going about testing completely wrong? I want the method to resolve so I can assert that the newItem property in Home.js has been reset. Happy New Year!

Home.test.js

import React from 'react';
import { mount } from 'enzyme';
import App from '../App';
import Provider from '../components/Provider';


test('should add to the provider list', () => {
  const wrapper = mount(
    <Provider>
      <App/>
    </Provider>
  );

  const child = wrapper.find('Home');
  const spy = jest.spyOn(child.instance(), 'addToList');

  child.setState({ newItem: { name: 'Cheese' } });
  wrapper.find('form').simulate('submit');

  expect(wrapper.state('list')).toHaveLength(1);
  expect(spy).toHaveBeenCalled();
});

component method in Home.js

addToList(event) {
    event.preventDefault();

    const { newItem } = this.state;

    if (!newItem.name) return;

    this.context.addToList(newItem)
      .then(() => {
        this.setState(() => ({
          newItem: { name: '' }
        }));
      })
      .catch(err => {
        //
      });
  }

component method in Provider.js

addToList(newItem) {
    return new Promise(resolve => {
      this.setState(state => {
        state.list.push(newItem);
        return state;
      }, resolve);
    });
  }

Posted on by:

Discussion

markdown guide
 

First of all, there doesn't seem to be a reason for the addToList function to return a promise. Second, I've found that relying on internal implementation of a component in tests makes them fragile (for example if later on you'll want to turn your component to a fictional component). In your case that would be where you add a spy on the function.
I'd suggest that you split the tests in two - one for the Provider and one for Home, and user mocks where applicable.

 

Agreed. React Testing Library is a pretty good way to test that abode testing implementation details. testing-library.com/