Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
496 views
in Technique[技术] by (71.8m points)

vue.js - VueJS / Jest : Mocking multiple fetch responses

I have a very simple component relying on two fetch calls :

<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>

I'm trying to test that component with Jest. While I found how to mock a Promise with Jest, I couldn't find a way to mock both fetch responses.

How can I do it without adding an external lib and without potentially refactoring my code?

question from:https://stackoverflow.com/questions/65837171/vuejs-jest-mocking-multiple-fetch-responses

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You could set global.fetch to a jest.fn() that uses the mockReturnValueOnce() API for each expected fetch call:

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

Before asserting any changes from the fetches, the test needs to flush their Promises for their then callbacks to be invoked. This can be done with:

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

Your test would look similar to this:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...