vuejs / vue-jest

Jest Vue transformer
MIT License
742 stars 159 forks source link

Test do not work with Vue 2.7 and Vue <script setup> Setup Api #525

Open marlokessler opened 1 year ago

marlokessler commented 1 year ago

Hi there,

Issue Description

I'm having trouble running unit tests with the Vue setup api using <script setup>. When running, the error states : [Vue warn]: Property or method "msg" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

Background

I created a plain new Vue 2 project via the Vue cli, updated to Vue 2.7.14 and migrated the Hello World component to the setup api. After migration the test does not work anymore. Nevertheless, the app is still running in dev mode and can be build.

The component now is:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script setup lang="ts">
import { defineProps, defineExpose, withDefaults } from "vue";
const props = withDefaults(defineProps<{ msg: string }>(), {
  msg: "",
});
// defineExpose({ msg: props.msg }); // `defineExpose` does not work either as proposed in https://stackoverflow.com/questions/74826923/how-to-access-a-variable-of-a-composition-api-vue-2-7-component/74887122#74887122 (also not exactly the same use case).
</script>

Used Dependencies

{
  "dependencies": {
    "core-js": "^3.25.3",
    "vue": "^2.7.14",
    "vue-class-component": "^7.2.3",
    "vue-router": "^3.5.1",
    "pinia": "^2.0.22"
  },
  "devDependencies": {
    "@types/jest": "^27.0.1",
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-typescript": "~5.0.0",
    "@vue/cli-plugin-unit-jest": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "@vue/eslint-config-typescript": "^9.1.0",
    "@vue/test-utils": "^1.1.3",
    "@vue/vue2-jest": "^27.0.0",
    "babel-jest": "^27.0.6",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-vue": "^8.0.3",
    "jest": "^27.0.5",
    "prettier": "^2.4.1",
    "ts-jest": "^27.0.4",
    "typescript": "~4.5.5",
    "vue-template-compiler": "^2.7.14"
  }
}

Does anybody know what to do? Thank you a lot in advance!

torbenwilkening commented 1 year ago

Hi there,

I was running into the same issue, and defineExpose is no option in my opinion. I got my <script setup> running by updating to Jest 29, in your case update these libraries:

    "@types/jest": "^27.0.1",
    "@vue/vue2-jest": "^27.0.0",
    "babel-jest": "^27.0.6",
    "jest": "^27.0.5",
    "ts-jest": "^27.0.4",

I'm not sure, you may have to make sure that @vue/compiler-sfc is there too, otherwise it will go into this catch block. In the same file, the processScriptSetup Function is not in your vue-jest 27.0.0, as far as I can see it came with 29.1.0 in September 2022

omrumbakitemiz commented 9 months ago

Hey, I also encountered this issue before, I upgraded to

"jest": "29.0.0",
"@vue/vue2-jest": "29.1.0",
"jest-environment-jsdom": "29.0.0"

and now my <setup script> component tests are working. 🎉🎉🎉🎉

Other deps:

"vue-template-compiler": "^2.7.14",
"vue": "2.7.14"

Also I'm using Typescript with babel my jest.config.js like below

preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  transform: {
    '.*\\.(vue)$': '@vue/vue2-jest',
  }
santoshkumar047 commented 8 months ago

@omrumbakitemiz I am also facing the same issue, even if my package.json configuration same as mentioned by you.

below ways can help us to resolve this

  1. (wrapper.vm as any)._setupProxy.someMethod

    not sure using _setupProxy is the proper way or not.

  2. 
    import {shallowMount,createLocalVue} from '@vue/test-utils';
    import VueCompositionApi from '@vue/composition-api';
    
    const localVue = createLocalVue()
    localVue.use(VueCompositionApi)
    shallowMount(require('./component.vue').default, {
      localVue,
    });