thevikas
thevikas

Reputation: 1639

how to re-render after getting axios response in jest test

My component:

componentDidMount() {
    // Make HTTP reques with Axios
    axios.get(APIConfig.api_profile()).then((res) => {
        // Set state with result
        this.setState(res.data);
        console.log('I was triggered during componentDidMount')
        console.log(res)
    });
}

And my test:

//@see https://github.com/ctimmerm/axios-mock-adapter
mock.onGet(APIConfig.api_profile()).reply(200, {
    "id_user": "1",
    "id_person": "1",
    "imageUrl": "",
    "email": "[email protected]",
    "name": "xyz xyz"
});

test('xyz', async() => {

    var ProfilePic2 =require('../../src/views/ProfilePic');
    const component = renderer.create(
        <ProfilePic/>
    );

    expect(component.state).toBeDefined();
    //tree.props.setProfile({})
    let tree = component.toJSON();
    await expect(tree).toMatchSnapshot();
});

The problem is that jest is testing on initial render while I need to test it after a API response is received. Therefore the snapshot that it is comparing to is also mostly empty.

I am not able make the test wait till after the second render. I am just trying await/async but cannot get it to work. I can see my api mocs was called from the console log.

Upvotes: 2

Views: 3908

Answers (1)

Andreas K&#246;berle
Andreas K&#246;berle

Reputation: 110932

The problem is that jest does not wait for async calls, have a look at the docs here. So the way how can you solve this is to give jest the promise that axios.get returns. This will not work if you use something that just mocks the async call inside axios. You have to mock axios complete out of your test like this:

jest.mock('axios', ()=> ({get:jest.fn()}))

now when importing axios into your file it will get an object where the get function is just a spy. To implement the spy so it will return a promise that you can give to jest you have to import it into your test:

import {get} from axios

now in your test create a resolved promise

test('xyz', async() = > {
  const p = Promise.resolve({
    data: {
      "id_user": "1",
      "id_person": "1",
      "imageUrl": "",
      "email": "[email protected]",
      "name": "xyz xyz"
    }
  })
  get.mockImplementation(() => p)
  var ProfilePic2 = require('../../src/views/ProfilePic');
  const component = renderer.create(
    <ProfilePic/>
  );
  expect(component.state).toBeDefined();
  //tree.props.setProfile({})
  let tree = component.toJSON();
  await p
  expect(tree).toMatchSnapshot();
});

Btw. I'm not sure if react-test-renderer will call componentDidMount, maybe you have to switch to enzyme.

Upvotes: 5

Related Questions