0

I'm having trouble setting up a just test case for this block of code.

fetchCustomers = () => {
    axios
      .get(URL)
      .then((response) => {
        this.setState({ customers: response });
      })
      .catch((error) => {
        console.log(error);
      });
  };

Here is what I tried so far

fetchMock.get("/api/customer/3", () => {
      return [{id:1, name: 'customer1', number: 23}];
    });

    wrapper.instance().fetchCustomers();

    expect(wrapper.state()).toEqual({
      customers: [{id:1, name: 'customer1', number: 23}]
    });

When I look at my code coverage it just tells me that I haven't got to the then part of the cascade and the error.

Any help would be appreciated!

  • It has to do with `axios` being asynchronous (a `promise`) and jest doesn't handle async code (like promises) very well. However, there's a workaround [mentioned here](https://stackoverflow.com/questions/44741102/how-to-make-jest-wait-for-all-asynchronous-code-to-finish-execution-before-expec), where you'll flush the promise by immediately resolving it, and then make assertions against the result. On a separate note, avoid using `console.log(error)` as it's harder to test against (you'll have to mock `console.log` and it silently fails without a UI indication); instead, set the error to state. – Matt Carlotta May 02 '20 at 02:42
  • @MattCarlotta I have to add that most time it's not Jest but developer's fault. When the code is test-ready, there's no necessity for promise flushing. – Estus Flask May 02 '20 at 06:57
  • What is fetchMock? The implementation depends on it. – Estus Flask May 02 '20 at 07:04

1 Answers1

1

The problem with fetchCustomers is that it doesn't return a promise and can't be chained. Even if this currently works in the component, this makes testing harder and prevents fetchCustomers from being composed with other methods.

It should be:

fetchCustomers = () => {
    return axios
      ...

Successful response is tested like:

fetchMock.get(...); // mock with 200 and data
jest.spyOn(axios, 'get');

await wrapper.instance().fetchCustomers();

expect(axios.get).toHaveBeenCalledWith(...);
expect(wrapper.state()).toEqual({...});

Failed response is tested like:

fetchMock.get(...); // mock with 500
jest.spyOn(axios, 'get');
jest.spyOn(console, 'log');

await wrapper.instance().fetchCustomers();

expect(axios.get).toHaveBeenCalledWith(...);
expect(console.log).toHaveBeenCalledWith(expect.any(Error));
expect(wrapper.state()).toEqual({});
Estus Flask
  • 206,104
  • 70
  • 425
  • 565