🐙
tanstack query のtestでAPIをMockする
概要
tanstack queryでAPIをモックするという話です。
一般的にAPIのモックはmswのようなモックサーバを使う方法とjestのモックを使う2種類のやり方があるかと思いますが、ここで紹介するのはjestの方です。
jestのmock
APIは適当にポケモンのピカチュウの情報を取得できる形とします。ここでピカチュウの取得APIは以下のように定義できます。
fetcher.ts
export const getPokemon = async (pokemonName: string) => {
return await fetch(`v2/pokemon/${pokemonName}`)
}
という形でポケモンを取得します。なお、ポケモンAPIは以下を参照しています。
続いて、コンポーネントの方を定義します。Container/presentationみたいに定義しています。
PokemonContainer.tsx
type PokemonContainerProps = { params: { pokemonName: string } }
export const PokemonContainer = ({ params }: PokemonContainerProps)=>{
const { data } = useQuery(['pokemon', params.pokemonName], async () => await getPokemon(params.pokemonName), { enabled: params.pokemonName !== undefined })
return (
<>
<Pokemon data={data} />
</>
)
}
pokemon.tsx
export const Pokemon = ({ data }: PokemonProps) => {
return (
<div>
{ data && <div>{data.id}</div> }
)
}
)
テストではgetPokemon
をmockすることでuseQuery
は動かすことができます。
__mock__/jest.ts
import * as Fetcher from '../fetcher'
import { mockPokemonPickachu } from '@/domain/pokemon/__mock__/mockPokemon'
//fetcherの中身全体をmockとして定義しておく
jest.mock('../fetcher')
//スパイモックとして返す
export function mockGetPokemon() {
return jest.spyOn(Fetcher, 'getPokemon').mockResolvedValue(mockPokemonPickachu)
}
コンポーネントのテストを記載します。
pokemonContainer.test.tsx
const setup = async ()=> {
render(<TestQueryClientProvider>
<PokemonContainer params={{ pokemonName: 'pickachu' }}/>
</TestQueryClientProvider>)
}
beforeEach(() =>{
jest.resetAllMocks()
})
describe('レンダリングテスト', () => {
test('APIをhook経由で呼び出せるか', async () =>{
//given
const getPokemon = mockGetPokemon()
setup()
//then
expect(await screen.findByText('25')).toBeInTheDocument()
//呼び出されたかチェック
expect(getPokemon).toHaveBeenCalled()
//引数が期待値通りであるかチェック
expect(getPokemon).toHaveBeenCalledWith('pickachu')
})
})
Discussion