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

IT技术 unit-testing reactjs jestjs axios
2021-05-25 03:51:00

我的组件:

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 响应后对其进行测试。因此,它所比较的​​快照也大多是空的。

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

1个回答

问题是 jest 不等待异步调用,请查看此处的文档所以你如何解决这个问题的方法是给 jestaxios.get返回的Promise如果您使用的东西只是模拟 axios 中的异步调用,这将不起作用。您必须axios像这样模拟完整的测试:

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

现在,当导入axios到您的文件中时,它将获得一个对象,其中 get 函数只是一个间谍。为了实现 spy,它会返回一个你可以给 jest 的Promise,你必须将它导入到你的测试中:

import {get} from axios

现在在您的测试中创建一个已解决的Promise

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,也许你必须改用酶。