0

Let say I have this code (from Create React App):

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {

  componentDidMount() {
    fetch('manifest.json').then(r => r.json()).then(data => {
      console.log(data);
    }).catch(e => console.log(e));
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;

How to test componentDidMount and get 100% code coverage?

I've used nock and isomorphic-fetch but, is there a better alternative?

Thanks.

Marco Afonso
  • 316
  • 2
  • 11
  • Possible duplicate of [Using Jest to spy on method call in componentDidMount](https://stackoverflow.com/questions/43245040/using-jest-to-spy-on-method-call-in-componentdidmount) – Rikin Jul 27 '18 at 01:01

2 Answers2

1

You can pass fetch into your component as a prop so in your tests you can pass a mocked version of fetch

example Class:

class Foo extends React.Component {
  componentDidMount () {
      const { fetch } = this.props
      ... your fetch code ... 
      }
    }
}

When you are using the component, you pass in real fetch:

const fetch = window.fetch // or however you're importing it

const UsesFoo = () => (
 <Foo fetch={fetch} />
)

Now your test: (assuming jest and shallow rendering)

const fakeFetch = jest.fn()

it('Should mock fetch', () => {
  const res = shallow(<Foo fetch={fakeFetch} />)
})
jsw324
  • 812
  • 7
  • 14
1

fetch you are referring to is a global in create-react-app based projects. Infact, afaik, they use isomorphic-fetch internally to expose this(as a poly-fill for legacy browsers). Since create-react-app comes with jest, you can use jest to mock the global before starting your tests.

Use the standard setupTests.js module to mock any global variable, like fetch.

You can use the global name space to access/mock them.

global.fetch = jest.fn();
Pubudu Dodangoda
  • 2,742
  • 2
  • 22
  • 38
  • Thanks. I had to use jest.fn().mockImplementation and create 2 window.Response, one I had to return with Promise.reject to cover the catch() case. Can you please improve your answer with my comment? thanks. – Marco Afonso Jul 27 '18 at 20:01