【问题标题】:Why does the 'then' part in async test fail in jest?为什么异步测试中的“then”部分开玩笑地失败了?
【发布时间】:2020-05-03 02:09:54
【问题描述】:

组件:

export const fetchList = () => {
  return API.get(AMPLIFY_ENPOINTS.default, API_URLS.list, { response: true });
}

const List: React.FC = () => {
  const dispatch = useDispatch();
  const setError = useError();

  useEffect(() => {
    fetchList()
      .then((response) => {
        if (response && response.data?.length) {
          dispatch(setList(response.data));
        }
      })
      .catch((error) => {
        setError(error);
      });
  }, [])
}

测试:

it('should fetch list', async () => {
  const wrapper = mount(
    <Provider store={store}>
      <List />
    </Provider>
  );
  API.get = jest.fn().mockImplementation(() => Promise.resolve({ data: mockList }));
  const response = await fetchList();
  console.log(store.getActions(), response); // HERE IS THE ISSUE
});

所以store.getActions()catch 块返回setError,这是为什么呢?它应该从then 块返回setList。我究竟做错了什么? response 变量返回 mockList 就好了。

编辑 它返回的错误是API not configured,我正在使用aws amplify。

【问题讨论】:

    标签: reactjs redux jestjs enzyme aws-amplify


    【解决方案1】:

    fetchList 在组件挂载时调用,模拟API.get 不影响第一次调用,第二次调用不做任何事情。通过为方法分配 spy 来模拟方法是一种不好的做法,因为它们在测试后无法恢复。

    fetchList 的问题在于它不能被窥探或模拟,因为它在它定义的同一模块中使用。它在useEffect 中创建的承诺不能被链接,需要刷新承诺以避免竞争条件。

    可以是:

      let flushPromises = () => new Promise(resolve => setImmediate(resolve));
    
      jest.spyOn(API, 'get').mockResolvedValue({ data: mockList });
    
      const wrapper = mount(
        <Provider store={store}>
          <List />
        </Provider>
      );
    
      await flushPromises();
    
      expect(store.getActions())...
    

    【讨论】:

      猜你喜欢
      • 2020-10-08
      • 2019-05-17
      • 2020-03-11
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 2019-07-21
      相关资源
      最近更新 更多