Subscribe on changes!

v3.2.45: regression in Vue Test Utils `wrapper.vm` for script setup variables

avatar
Nov 11th 2022

Vue version

3.2.45

Link to minimal reproduction

https://stackblitz.com/edit/vitest-dev-vitest-1djhp4?file=components%2FHello.vue,test%2Fbasic.test.ts,package.json&initialPath=__vitest__

Steps to reproduce

Given a component like:

<script setup lang="ts">
import { computed, ref } from 'vue';

const count = ref(4);
const times = ref(2);
const result = computed(() => count.value * times.value);

defineExpose({
  result,
});
</script>

<template>
  <div>{{ count }} x {{ times }} = {{ result }}</div>
</template>

VTU allows to write a test like:

import { mount } from '@vue/test-utils';
import Hello from '../components/Hello.vue';

test('mount component', async () => {
  expect(Hello).toBeTruthy();

  const wrapper = mount(Hello);

  expect(wrapper.text()).toContain('4 x 2 = 8');
  // result is exposed
  expect(wrapper.vm.result).toBe(8);
  // count and times are not exposed, but VTU exposes vm.$.proxy
  expect(wrapper.vm.count).toBe(4);
  expect(wrapper.vm.times).toBe(2);
});

VTU can access count, times and result (even if only result is exposed) because we are internally using vm.$.proxy for the VM in script setup components

https://github.com/vuejs/test-utils/blob/ff93e5e60ac8482cf4326f9f83fffa8dac08f8b6/src/vueWrapper.ts#L49-L62

Vue v3.2.45 introduced changes that are breaking this use case.

Is there a way that we can keep this feature in VTU? Either by making the recent changes less breaking, or using another workaround in VTU.

What is expected?

The unit test should succeed, as it does with Vue v3.2.44

What is actually happening?

wrapper.vm no longer has access to script setup variables

System Info

No response

Any additional comments?

No response

avatar
Nov 11th 2022

This is an intended change to solve dev/prod inconsistencies (https://github.com/vuejs/core/issues/6248), so we should try and see that we can keep it. I think test-utils could use instance.setupState instead?

avatar
Nov 11th 2022

Thanks @LinusBorg I think setupState lacks $, $options, and others, which breaks other test cases.

avatar
Nov 11th 2022

You would have to mimick what the component proxy itself does to an extend: i.e. check the setup state for the accessed key first, and if that fails, try the proxy (for all those public APIs)

avatar
Nov 11th 2022

Ha! I was coming to the same proxy idea on my side: combining with your code, I have something that works with v3.2.45 and v3.2.44 Thanks for your help @LinusBorg 👍

https://github.com/vuejs/test-utils/pull/1858

avatar
Nov 11th 2022

😮 thanks

avatar
Nov 12th 2022

Closing as intended - it's important to keep the prod/dev behavior consistent for normal users, and it only affects dev behavior, so this change is considered a fix.