I've been trying out vitest, but I've gotten stuck when i tried to run tests on a component that utilizes the PokeAPI. I figured creating a mock setup would fix it, but to no avail.
The component that has the logic is fairly simple. Form, with input and submit button where you enter the name of a pokemon and then the result is shown.
<template>
<h1>Pokedex thing</h1>
<form @submit.prevent="search">
<!-- Input field and submit button -->
<input v-model="searchTerm" type="text" placeholder="Search for a Pokemon" />
<button type="submit">Search</button>
</form>
<p v-if="searching">searching...</p>
<div v-if="searchResult.pokemon && !searching" data-key="pokemon">
<p>{{ capitalized }}</p>
<img :src="searchResult.pokemon.sprites.front_default" alt="Pokemon" />
</div>
</template>
<script setup lang="ts">
import { reactive, ref, computed } from "vue";
import { AxiosError, AxiosResponse } from "axios";
import axios from "axios";
const searchTerm = ref("");
const searching = ref(false);
const searchResult = reactive({
pokemon: undefined as { name: string; sprites: { front_default: string } } | undefined,
});
const search = async () => {
searching.value = true;
await axios
?.get(`https://pokeapi.co/api/v2/pokemon/${searchTerm.value.toLowerCase()}`)
.then((response: AxiosResponse) => {
searchResult.pokemon = response.data;
searching.value = false;
})
.catch((e: AxiosError) => {
searching.value = false;
if (e.response?.status === 404) {
searchResult.pokemon = {
name: "Pokemon not found",
sprites: {
front_default: "https://via.placeholder.com/150",
},
};
}
});
};
const capitalized = computed(
() => `${searchResult.pokemon?.name.charAt(0).toUpperCase()}${searchResult.pokemon?.name.slice(1)}`,
);
</script>
The test is pretty straight forward. I mounts the component, finds the input, sets the value and presses the button. From there on, i've fallen into despair
it("should search pokemon", async () => {
const wrapper: VueWrapper = mount(Pokedex);
const input = wrapper.find("input");
await input.setValue("bulbasaur");
await wrapper.find("button").trigger("click");
await flushPromises();
const result = wrapper.get("[data-key=pokemon]");
console.log(result);
console.log(wrapper.text());
});
For the mocks, i followed the guide from vitest, linked here, and just filled in with the URL's that I used.
//imports etc..
export const restHandlers = [
rest.get(
"https://pokeapi.co/api/v2/pokemon/bulbasaur",
(req: RestRequest, res: ResponseComposition, ctx: RestContext) => {
console.log("fjkshdgkolsjhglkjsdhg");
return res(ctx.status(200), ctx.json(testPokemon));
},
),
rest.get(
"https://pokeapi.co/api/v2/pokemon/invalid",
(req: RestRequest, res: ResponseComposition, ctx: RestContext) => {
return res(ctx.status(404));
},
),
];
// setupServer, beforeAll, afterAll, afterEach.
When I try to get the pokemon-div, it throws me an error, saying it doesn't exist. I figure its because it hasnt been rendered.
I'm new to vitest and I've been trying to google everything that comes to mind, but no luck. I have a feeling, as if the setupServer function isnt working properly.