Description
Describe the bug
This is a bit hard to describe but hopefully the reproduction demo will clear things up.
I have a big project with 7000+ thousand tests. Recent ones are good, old ones are bad and rely heavily on .vm
.
I'm migrating the code base to a monorepo and the design system is now bundled as separate package by vite
and the apps import the components’ bundled version instead of the .vue
, tests inherently do too. I noticed that most of the tests that rely on vm
stopped working.
wrapper.findComponent(VComp).vm.someMethod // someMethod is always undefined, before bundle it wasn't.
Note
I don't know if this is VTU
fault or if it's by design, but having in mind that if I import the raw .vue
component instead of the bundled .js
version everything works I am assuming it is — Please close this issue if my assumption is wrong.
To Reproduce
https://stackblitz.com/edit/vitest-dev-vitest-h8drorow?file=apps%2Fdemo%2Ftest%2Fbasic.test.ts
Should run automatically, if not npm run test
Expected behavior
exposed properties via defineExpose
are available though of findComponent
returned VueWrapper
Assuming a basic VExample.vue
component
<!-- packages/ui/src/VExample.vue -->
<template>
<div>Example</div>
</template>
<script setup>
const props = defineProps({
a: String,
});
const exposedFn = () => {
console.log('hey');
};
defineExpose({
exposedFn,
});
</script>
Bundles to
import { openBlock as o, createElementBlock as p } from "vue";
const l = {
__name: "VExample",
props: {
a: String
},
setup(n, { expose: e }) {
return e({
exposedFn: () => {
console.log("hey");
}
}), (s, t) => (o(), p("div", null, "Example"));
}
};
export {
l as VExample
};
Faulty test
import { VExample as VExampleRaw } from '../../packages/ui/src/VExample.vue'
import { VExample as VExampleBundled } from 'ui'
// swapping VExampleBundled per VExampleRaw in the components option makes it pass.
it('finds exposed "vm" properties in *bundled* component wrapper via findComponent', () => {
const wrapped = mount({
components: {
VExampleBundled,
},
template: `<div><v-example /></div>`,
});
const test = wrapped.findComponent({ name: 'VExample' });
console.log(test.vm); // only has "a" prop
expect(test.exists()).toBe(true);
// fails
expect(test.vm.exposedFn).toBeInstanceOf(Function);
});
Related information:
vue: 3.5.13
@vue/test-utils: 2.4.6
Additional context
The same behaviour is not found in mount
. When passing the bundled version of a component to mount
, exposed properties are exposed correctly to vm, that's why I think it's a bug in findComponent
.
Activity