'Vue Jest [Vue warn]: data functions should return an object: when mocking child components
I have this component, which is parent to 4 others. I then mocked some child components to test their features, however when I test them I get the error
[Vue warn]: data functions should return an object:
What would be a better way to mock child components? All my tests are successful, but I'm trying to get around the error of data functions should return an object. The stuff in French is irrelevant as far as the code goes.
<template>
<div class="container-12 m-5">
<div class="row">
<div class="col-9">
<actions
@clickFight="onFight"
@clickEnd="onEnd"
@clickRepair="onRepair"
></actions>
</div>
<div class="col-3">
<mission ref="mission" @forceRouteLeave="forceRouteLeave"></mission>
</div>
</div>
<div class="row">
<div class="col-6">
<player
v-bind:login-name="$attrs.name"
v-bind:ship="$attrs.ship"
@forceRouteLeave="forceRouteLeave"
ref="player"
>
</player>
</div>
<div class="col-6">
<enemy ref="enemy"></enemy>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import Actions from '@/components/Actions.vue'
import Enemy from '../components/Enemy.vue'
import Player from '../components/Player.vue'
import Mission from '../components/Mission.vue'
export default {
name: 'Game',
components: {
Actions,
Enemy,
Player,
Mission
},
data () {
return {
score: 0,
avoidRouteLeave: false // To force route leave on player death/final mision
}
},
methods: {
async onFight () {
// Damage to player
this.$refs.player.getShotAt(this.$refs.enemy.shootAt())
// Damage to enemy
this.$refs.enemy.getShotAt(this.$refs.player.shootAt())
},
async onEnd () {
this.nextMission()
this.$refs.enemy.getNewEnemy()
},
async onRepair () {
this.$refs.player.repair()
this.onEnd()
},
forceRouteLeave () {
this.avoidRouteLeave = true
},
getScore () {
return this.$refs.player.getScore()
},
addToScore (score) {
this.$refs.player.addToScore(score)
},
nextMission () {
this.$refs.mission.nextMission()
}
},
async beforeRouteLeave (to, from, next) {
if (this.avoidRouteLeave === true) {
next()
} else {
await this.$bvModal
.msgBoxConfirm(
'Voulez-vous vraiment quitter cette page? Toute votre progression sera perdue.',
{
okTitle: 'OUI',
cancelTitle: 'NON'
}
)
.then(value => {
if (value === true) {
next()
}
})
}
}
}
</script>
<style>
.card {
height: 95%;
}
</style>
-----The tests-----
import { shallowMount } from '@vue/test-utils'
import Game from '@/views/Game'
import flushPromises from 'flush-promises'
import Mission from '@/components/Mission'
import Player from '@/components/Player'
import Enemy from '@/components/Enemy'
jest.mock('@/components/Mission')
jest.mock('@/components/Player')
jest.mock('@/components/Enemy')
describe('Game.vue', () => {
test('Si avoidRouteLeave est faux et que beforeRouteLeave est appeler, un message box est appeler, si on répond non, on ne quitte pas la page', async () => {
const next = jest.fn()
const msgBoxConfirm = jest.fn().mockResolvedValue(false)
const wrapper = await gameShallowMount({
$router: {
push: () => {}
},
$bvModal: {
msgBoxConfirm: () => msgBoxConfirm()
},
global: {
stubs: {
Mission: true,
Player: true,
Enemy: true
}
}
})
wrapper.vm.avoidRouteLeave = false
await Game.beforeRouteLeave.call(wrapper.vm, undefined, undefined, next)
expect(next).not.toHaveBeenCalled()
expect(msgBoxConfirm).toHaveBeenCalledTimes(1)
})
test('Si avoidRouteLeave est faux et que beforeRouteLeave est appeler, un message box est appeler, si on répond oui, on quitte la page', async () => {
const next = jest.fn()
const msgBoxConfirm = jest.fn().mockResolvedValue(true)
const wrapper = await gameShallowMount({
$router: {
push: () => {}
},
$bvModal: {
msgBoxConfirm: () => msgBoxConfirm()
}
})
wrapper.vm.avoidRouteLeave = false
await Game.beforeRouteLeave.call(wrapper.vm, undefined, undefined, next)
expect(next).toHaveBeenCalled()
expect(msgBoxConfirm).toHaveBeenCalledTimes(1)
})
test('Si avoidRouteLeave est vrai et que beforeRouteLeave est appeler, on quitte la page', async () => {
const next = jest.fn()
const wrapper = await gameShallowMount({
$router: {
push: () => {}
}
})
wrapper.vm.avoidRouteLeave = true
await Game.beforeRouteLeave.call(wrapper.vm, undefined, undefined, next)
expect(next).toHaveBeenCalled()
})
test('Appeler forceRouteLeave() met avoidRouteLeave à vrai', async () => {
const wrapper = await gameShallowMount()
wrapper.vm.avoidRouteLeave = false
wrapper.vm.forceRouteLeave()
expect(wrapper.vm.avoidRouteLeave).toBeTruthy()
})
test('Appeler getScore() retourne le score de son enfant player', async () => {
const expected = 100
const getScoreMock = jest.fn().mockResolvedValue(expected)
Player.methods.getScore = getScoreMock
const wrapper = await gameShallowMount()
const result = await wrapper.vm.getScore()
expect(result).toStrictEqual(expected)
expect(getScoreMock).toHaveBeenCalled()
})
test('Appeler addToScore() ajoute le score à son enfant player', async () => {
const addToScoreMock = jest.fn()
Player.methods.addToScore = addToScoreMock
const wrapper = await gameShallowMount()
wrapper.vm.addToScore()
expect(addToScoreMock).toHaveBeenCalled()
})
test('Appeler nextMission() déclenche la méthode nextMission() de son enfant mission', async () => {
const nextMissionMock = jest.fn()
Mission.methods.nextMission = nextMissionMock
const wrapper = await gameShallowMount()
wrapper.vm.nextMission()
expect(nextMissionMock).toHaveBeenCalled()
})
test('Appeler onRepair() déclenche la méthode nextMission() et lance la méthode repair de son enfant player', async () => {
const repairMock = jest.fn()
Player.methods.repair = repairMock
const wrapper = await gameShallowMount()
jest.spyOn(wrapper.vm, 'onEnd')
wrapper.vm.onRepair()
expect(repairMock).toHaveBeenCalled()
expect(wrapper.vm.onEnd).toHaveBeenCalled()
})
test('Appeler OnEnd() appelle nextMission() et nextEnemy() ', async () => {
const nextEnemyMock = jest.fn()
Enemy.methods.getNewEnemy = nextEnemyMock
const wrapper = await gameShallowMount()
jest.spyOn(wrapper.vm, 'nextMission')
await wrapper.vm.onEnd()
expect(nextEnemyMock).toHaveBeenCalled()
expect(wrapper.vm.nextMission).toHaveBeenCalled()
})
})
async function gameShallowMount (mocks) {
const wrapper = shallowMount(Game, {
stubs: { mission: Mission, player: Player, enemy: Enemy },
mocks: mocks
})
await flushPromises()
return wrapper
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
