Jest.js 如何模拟两个不同的fetch调用,并将自定义数据作为参数提供给它们?

6yoyoihd  于 2023-06-20  发布在  Jest
关注(0)|答案(1)|浏览(152)

在我的组件中有两个不同的fetch调用

const fetchPopularCuisines = async() => {
    const data = await fetch(URL2)
    const jsonData = await data.json()
    setPopularCuisines(jsonData?.data?.cards[1])
}

const fetchSuggestions = async() =>{
    const data = await fetch(URL1)
    const jsonData = await data.json() 
    setSearchResults(jsonData?.data?.suggestions)
}

我尝试使用RTL测试我的组件,代码如下:

// POPULAR_CUISINES_DATA is the data which the API gives when I call fetchPopularCuisines()

global.fetch = jest.fn(()=>{
    return Promise.resolve({
        json : () => Promise.resolve(POPULAR_CUISINES_DATA)
    })
})

// testing the code for the first function above[fetchPopularCuisines()]
test('popular cuisines should render after making an API call', async ()=>{

    const searchBar = render(
        <Provider  store={store}>
            <SearchBar />
        </Provider>
    )
    await waitFor(()=>{
        const cuisinesList = searchBar.getAllByTestId('cuisines-list')
        expect(cuisinesList.length).toBe(12)
    } )

})

直到上面一切正常。现在,测试第二个函数[fetchSuggestions()]的代码会破坏代码,因为我不确定如何向fetch调用提供不同的数据,而不是POPULAR_CUISINES_DATA。我想传递变量SEARCH_RESULTS_DATA用于第二个fetch调用的模拟。
我该怎么做?
基本上,如果我有'n'个不同的fetch调用,我如何模拟它们并在每种情况下向Promise. resolve()提供自定义数据?

prdp8dxp

prdp8dxp1#

你可以模仿fetch函数的实际实现,如下所述:https://jestjs.io/docs/mock-functions#mock-implementations
一些更详细的例子在这篇博客文章中:https://kentcdodds.com/blog/stop-mocking-fetch
你应该以这样的方式结束:

async function mockFetch(url, config) {
  switch (url) {
    case URL2: {
      return Promise.resolve({
        json : () => Promise.resolve(POPULAR_CUISINES_DATA)
      })
    }
    case URL1: {
      return Promise.resolve({
        json : () => Promise.resolve(SEARCH_RESULTS_DATA )
      })
    }
    default: {
      throw new Error(`Unhandled request: ${url}`)
    }
  }
}

beforeAll(() => jest.spyOn(window, 'fetch'))
beforeEach(() => window.fetch.mockImplementation(mockFetch))

相关问题