Recommended implementation for writing unit tests with villus
See original GitHub issueI’m trying to write unit tests in Jest for my Vue application, but I’m running into problems because of Villus, and I’m not entirely sure how I should go about mocking things like useMutation and useQuery. Any tips?
This is the error I’m getting:
● GameCard.vue › renders platforms and developers when passed
Cannot detect villus Client, did you forget to call `useClient`?
57 | });
58 |
> 59 | const { execute: executeFavoriteGame } = useMutation(FavoriteGameDocument);
The Jest test looks like this:
import { createLocalVue, mount } from '@vue/test-utils'
import GameCard from '@/components/GameCard.vue'
const localVue = createLocalVue();
describe('GameCard.vue', () => {
it('renders platforms and developers when passed', () => {
const wrapper = mount(GameCard, {
stubs: ['router-link', 'router-view'],
localVue,
propsData: {
game: {
id: 1,
platforms: {
nodes: [
{
id: 1,
name: 'Nintendo Switch'
}
]
},
developers: {
nodes: [
{
id: 1,
name: 'Valve'
}
]
},
isFavorited: true
}
}
})
expect(wrapper.text()).toMatch('Nintendo Switch')
})
})
and my component looks like this:
<template>
<div class="custom-card game-card">
<router-link :to="{ name: 'Game', params: { id: game.id } }" class="card-container">
<figure class="game-cover">
<img v-if="game.coverUrl !== null" :src="game.coverUrl" />
<img v-else src="@/assets/images/no-cover.png"/>
</figure>
<div class="card-content">
<p class="title is-4 mr-10">{{ game.name }}</p>
<p class="subtitle is-6" v-if="platforms !== null">{{ platforms }}</p>
<p class="subtitle is-6" v-if="developers !== null">{{ developers }}</p>
</div>
</router-link>
<!-- Game card Dropdown -->
<div class="dropdown dropdown-dynamic game-card-dropdown is-right" :class="{ 'is-active': isActive }" v-if="userSignedIn">
<div class="dropdown-trigger">
<button class="button is-borderless is-shadowless" aria-haspopup="true" aria-controls="dropdown-menu" @click="toggleActive">
<SvgIcon :name="'chevron-down'" :classes="['icon']" :size="15" />
</button>
</div>
<div class="dropdown-menu" id="dropdown-menu" role="menu">
<div class="dropdown-content">
<a v-if="game.isFavorited || localIsFavorited" class="dropdown-item" @click="unfavoriteGame">Unfavorite</a>
<a v-else class="dropdown-item" @click="favoriteGame">Favorite</a>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Company, FavoriteGameDocument, Platform, UnfavoriteGameDocument } from '@/generated/graphql';
import { computed, defineComponent, ref } from '@vue/composition-api';
import SvgIcon from '@/components/SvgIcon.vue';
import { useMutation } from 'villus';
export default defineComponent({
name: 'GameCard',
components: {
SvgIcon
},
props: {
game: {
required: true,
type: Object
}
},
setup(props, context) {
const platforms = computed(() => {
if (props.game.platforms.nodes.size === 0) { return null; }
return props.game.platforms.nodes.map((p: Platform) => p.name).join(', ');
});
const developers = computed(() => {
if (props.game.developers.nodes.size === 0) { return null; }
return props.game.developers.nodes.map((d: Company) => d.name).join(', ');
});
const { execute: executeFavoriteGame } = useMutation(FavoriteGameDocument);
const { execute: executeUnfavoriteGame } = useMutation(UnfavoriteGameDocument);
let isActive = ref<boolean>(false);
// Tracks whether the game has been favorited, will be toggled when the
// mutation is executed so we don't have to reload the game record.
let localIsFavorited = ref<boolean>(props.game.isFavorited);
const favoriteGame = () => {
executeFavoriteGame({ id: props.game.id }).then(() => {
toggleActive();
localIsFavorited.value = true;
});
};
const unfavoriteGame = () => {
executeUnfavoriteGame({ id: props.game.id }).then(() => {
toggleActive();
localIsFavorited.value = false;
});
};
const toggleActive = () => isActive.value = !isActive.value;
const userSignedIn = computed(() => {
return context.root.$store.state.userSignedIn;
});
return {
isActive,
platforms,
developers,
favoriteGame,
unfavoriteGame,
toggleActive,
userSignedIn,
localIsFavorited
};
}
});
</script>
I’m using Vue 2.x with TypeScript and @vue/composition-api
.
See similar docs for Apollo: https://apollo.vuejs.org/guide/testing.html#testing
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (6 by maintainers)
Top Results From Across the Web
Writing Tests - villus
In this guide, you will find some recommendations and examples on how to write unit tests for components using villus . Testing tools...
Read more >Unit Tests, How to Write Testable Code, and Why It Matters
In this article, I will show that unit testing itself is quite easy; the real problems that complicate unit testing, and introduce expensive...
Read more >Get started with unit testing - Visual Studio (Windows)
Use Visual Studio to define and run unit tests to maintain code health, and to find errors and faults before your customers do....
Read more >Unit Testing Best Practices: 9 to Ensure You Do It Right
Do you know any unit testing best practice? In this post, you'll learn nine of them so you can get started the right...
Read more >All about unit testing: 11 best practices and overview
1. Write tests for a number of scenarios · 2. Write good test names · 3. Set up automated tests · 4. Write...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’ve added an initial testing guide, it might be missing a lot so let me know what is missing and I will try adding it. It should have an example for you.
https://villus.logaretm.com/guide/testing
Yea, I think it is important to have a testing guide, I will give you some quick tips here.
villus
owntests
fetch
or any network calls, I actually prefer to mock a server using mswjsflush-promises
or a timeout.villus
client with global.provides, theVILLUS_CLIENT
symbol is exported just for that.I will work around adding a testing guide this week probably.