Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test API calls in react using jest and enzyme?

I have a React container in which I am making the API call and would like to be able to test this using jest and enzyme but unsure how to.

This is my code:

import React from "react";
import Search from "../../components/Search";
import { API_KEY } from "../../../config";

class SearchContainer extends React.Component {
  state = {
    articles: []
  };

  performSearch = event => {
    fetch(
      `http://content.guardianapis.com/search?q=${event}&api-key=${API_KEY}`
    )
      .then(response => response.json())
      .then(data => this.setState({ articles: data.response.results }));
  };

  render() {
    return (
      <Search
        performSearch={this.performSearch}
        articles={this.state.articles}
      />
    );
  }
}

export default SearchContainer;
like image 446
jingteng Avatar asked Apr 17 '18 22:04

jingteng


2 Answers

That's a great thing about unit testing, they force you to write better code. So to properly test this component, you should do the following:

  1. Extract performSearch from The component into a separate file e.g. api.js
  2. Mock performSearch in your api.js file (jest: mock a module)

  3. Now you can test that the fetch function was called.

Note that with this code organization you could separately test your API calls and your SearchContainer without calling your API service.

like image 101
Val Avatar answered Sep 22 '22 02:09

Val


I would approach this by extracting performSearch out into a module that wraps fetch. See this great article on testing things you don't own.

After that, you may not need SearchContainer any more if you store the articles state within the Search component. Since you're already using dependency injection with the performSearch property, you can pass in a mock object in place of it and use jest.fn() to ensure it is called.

For example:

const fakePerformSearch = jest.fn();
const component = Shallow(<Search performSearch={fakePerformSearch}/>);
expect(fakePerformSearch).toHaveBeenCalled();

And then test your new fetch wrapper as you would any JavaScript.

like image 28
Steve Hansell Avatar answered Sep 22 '22 02:09

Steve Hansell