Skip to content

Commit 24b3fa8

Browse files
committed
fix: allow spying on non-exposed script setup functions
Fixes vuejs#1859 The proxy needs to implement `defineProperty` to allow spying.
1 parent 59331e9 commit 24b3fa8

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/vueWrapper.ts

+17
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,29 @@ function createVMProxy<T extends ComponentPublicInstance>(
4545
return Reflect.set(vm, key, value, receiver)
4646
}
4747
},
48+
has(vm, property) {
49+
return Reflect.has(setupState, property) || Reflect.has(vm, property)
50+
},
51+
defineProperty(vm, key, attributes) {
52+
if (key in setupState) {
53+
return Reflect.defineProperty(setupState, key, attributes)
54+
} else {
55+
return Reflect.defineProperty(vm, key, attributes)
56+
}
57+
},
4858
getOwnPropertyDescriptor(vm, property) {
4959
if (property in setupState) {
5060
return Reflect.getOwnPropertyDescriptor(setupState, property)
5161
} else {
5262
return Reflect.getOwnPropertyDescriptor(vm, property)
5363
}
64+
},
65+
deleteProperty(vm, property) {
66+
if (property in setupState) {
67+
return Reflect.deleteProperty(setupState, property)
68+
} else {
69+
return Reflect.deleteProperty(vm, property)
70+
}
5471
}
5572
})
5673
}

tests/components/ScriptSetup.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ const inc = () => {
1212
</script>
1313

1414
<template>
15-
<button @click="inc">{{ count }}</button>
15+
<button @click="inc()">{{ count }}</button>
1616
<Hello />
1717
</template>

tests/expose.spec.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { describe, expect, it, vi } from 'vitest'
22
import { nextTick } from 'vue'
33
import { mount } from '../src'
44
import Hello from './components/Hello.vue'
@@ -61,4 +61,19 @@ describe('expose', () => {
6161
await nextTick()
6262
expect(wrapper.html()).toContain('2')
6363
})
64+
65+
it('spies on vm with <script setup> even without defineExpose()', async () => {
66+
const wrapper = mount(ScriptSetup)
67+
68+
const spiedIncrement = vi
69+
// @ts-ignore we need better types here, see https://github.com/vuejs/test-utils/issues/972
70+
.spyOn(wrapper.vm, 'inc')
71+
.mockImplementation(() => {})
72+
73+
await wrapper.find('button').trigger('click')
74+
await nextTick()
75+
76+
expect(spiedIncrement).toHaveBeenCalled()
77+
expect(wrapper.html()).toContain('0')
78+
})
6479
})

0 commit comments

Comments
 (0)