Description
Subject of the issue
I have a vue 3 project using <script setup>
tags
I import a composable into a component on the project.
I attempt to mock the composable in my test.
I observe that the composable is mocked accordingly during debugs of the test however once the debugger jumps to <script setup>
the composable is observed and is not mocked
Steps to reproduce
- create a vue 3 project and add a component that has a
<script setup>
tag. - create a composable that returns a handful of variables:
// fooComposable.js
export function useFooComposable () {
...
return {
bahComputedProperty, // contrive a computed property that simply returns false
bazMethod, // contrive a method
}
}
- import the composable above into the component from step 1 and destructure the properties from the call and wire them up to a simple event...
import { useFooComposable } from '~/composables/fooComposable.js'
const { bahComputedProperty, bazMethod } = useFooComposable()
const myEvent = () => {
if (bahComputedProperty) bazMethod()
}
<template>
<button @click="myEvent">Click</button>
</template>
- create a spec for the above component and mock the composable with something to the effect of the below:
(note I have tried numerous different variations on this them, with and without vi.fn() )
import ...
import { useFooComposable } from '@/composables/fooComposable.js'
vi.mock( '@/composables/fooComposable.js', () => ({
useFooComposable: vi.fn().mockReturnValue({ // I've tried this as a pojo closure as well, no difference
bahComputedProperty: computed(() => return true), // i've tried this as a computed, a primitive, a vi.fn and a pojo getter, no difference
bazMethod: vi.fn(), // i've tried this as a pojo method, no difference.
}),
}))
- write a vi test that mounts the component, grabs
bazMethod
from useFooComposable, clicks the button and thereafter:expect(bazMethod).toBeCalled()
Expected behaviour
because the useFooComposable mock has switched bahComputedProperty
to true, the test should fire bazMethod.
Actual behaviour
the debugger observes that both bahComputedProperty
and bazMethod
are mocked in the test script but when the debugger jumps to the myEvent
call in the component, neither the property nor the event have been mocked. This isn't an issue for the contrived event here but handling all permutations of composables makes for extremely fragile tests in production code.
Possible Solution
I've tried setting it as a mock and I've tried directly altering wrapper.vm.bazMethod
after the fact and neither gives me any change.
my colleague has had some success with
import * as bahComposable from ...
vi.spyon(bahComposable, 'useComposable').mockImplementation(() => { ... })
but this feels obscure given how much demand there is for composables in Vue 3. It simply feels - in the first place - like VTU isn't honouring vi.mock and that it probably should since this is the preferred manner of mocking imports in the given framework.