在玩笑测试中获得 axios 响应后如何重新渲染

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

我的组件:

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)
    });
}

我的测试:

//@see https://github.com/ctimmerm/axios-mock-adapter
mock.onGet(APIConfig.api_profile()).reply(200, {
    "id_user": "1",
    "id_person": "1",
    "imageUrl": "",
    "email": "xyz@zyz.com",
    "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();
});

问题是 jest 正在对初始渲染进行测试,而我需要在收到 API 响应后对其进行测试。因此,它所比较的​​快照也大部分是空的。

我无法让测试等到第二次渲染之后。 我正在尝试 await/async 但无法正常工作。 我可以看到我的 api mocs 是从控制台日志中调用的。

问题是 jest 不等待异步调用,请查看文档 here。所以解决这个问题的方法是开玩笑地承诺 axios.get returns。如果您使用仅模拟 axios 中的异步调用的东西,这将不起作用。您必须像这样模拟 axios 完成测试:

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

现在,当将 axios 导入您的文件时,它将获得一个对象,其中 get 函数只是一个间谍。要实现间谍,它会 return 一个你可以开玩笑的承诺,你必须将它导入到你的测试中:

import {get} from axios

现在在你的测试中创建一个已解决的承诺

test('xyz', async() = > {
  const p = Promise.resolve({
    data: {
      "id_user": "1",
      "id_person": "1",
      "imageUrl": "",
      "email": "xyz@zyz.com",
      "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();
});

顺便说一句。我不确定 react-test-renderer 是否会调用 componentDidMount,也许你必须切换到酶。