VueJS / Jest:模拟多个获取响应

Posted

技术标签:

【中文标题】VueJS / Jest:模拟多个获取响应【英文标题】:VueJS / Jest : Mocking multiple fetch responses 【发布时间】:2021-04-26 10:46:20 【问题描述】:

我有一个非常简单的组件,它依赖于两个 fetch 调用:

<template>
  <div>
    <div ng-if="this.foo">
       foo.name 
    </div>
    <div ng-if="this.bar">
       bar.address 
    </div>
  </div>
</template>

<script>
export default 
  name: 'identity-card',
  data() 
    return 
      foo:undefined,
      bar:undefined
    
  
  created() 
    Promise.all([
      fetch('http://ul/to/api/foo'),
      fetch('http://ul/to/api/bar')
    ]).then(async (response) => 
      this.foo = await response[0].json();
      this.bar = await response[1].json();
    )
  

</script>

我正在尝试使用Jest 测试该组件。 虽然我找到了如何用Jest 模拟Promise,但我找不到同时模拟fetch 响应的方法。

如何在不添加外部库且不重构代码的情况下做到这一点?

【问题讨论】:

你的测试代码是什么样的?您可能需要使用异步并按特定顺序执行刷新和滴答,以便获取请求正确解析。 我做了文档推荐的原因:global.fetch = jest.fn(() =&gt; Promise.resolve(json: () =&gt; Promise.resolve( rates: CAD: 1.42 ),)); 但这没什么帮助,因为你不能模拟多个 fetches 【参考方案1】:

您可以将global.fetch 设置为jest.fn(),该mockReturnValueOnce() API 用于每个预期的fetch 调用:

const makeFetchResp = value => ( json: async() => value )   // mock fetch().json()
const mockFetch = jest.fn()
                   .mockReturnValueOnce(makeFetchResp(true))  // 1st fetch() returns true
                   .mockReturnValueOnce(makeFetchResp(false)) // 2nd fetch() returns false
global.fetch = mockFetch

在断言来自fetches 的任何更改之前,测试需要刷新它们的Promises,以便调用它们的then 回调。这可以通过以下方式完成:

const flushPromises = () => new Promise(r => setTimeout(r))
await flushPromises()

您的测试将与此类似:

it('fetches foo bar', async () => 
  const makeFetchResponse = value => ( json: async() => value )
  const mockFetch = jest.fn()
    .mockReturnValueOnce(makeFetchResponse(true))
    .mockReturnValueOnce(makeFetchResponse(false))
  global.fetch = mockFetch

  const wrapper = shallowMount(MyComponent)

  await flushPromises()

  expect(mockFetch).toHaveBeenCalledTimes(2)
  expect(wrapper.vm.foo).toBeTruthy()
  expect(wrapper.vm.bar).toBeFalsy()
)

【讨论】:

您的代码在我的测试用例中运行良好。感谢您分享您的知识。现在我对测试/模拟多个 fetch api 调用有了一个想法。

以上是关于VueJS / Jest:模拟多个获取响应的主要内容,如果未能解决你的问题,请参考以下文章

开玩笑地模拟获取响应的 blob 的 fetch() 函数

在 jest-react 中使用 MockedProvider 会导致错误“查询没有更多的模拟响应”

使用 Jest 在 VueJS 组件中模拟自定义模块

Vue-test-utils 模拟从另一个组件获取响应

模拟交叉获取

Django + Vuejs 无法从响应头中获取 Csrftoken