Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 3 initial unit test does not work: Property "msg" was accessed during render but is not defined on instance. #5974

Closed
E-jarod opened this issue Oct 16, 2020 · 19 comments · Fixed by #5975

Comments

@E-jarod
Copy link

E-jarod commented Oct 16, 2020

Version

3.0.0

Reproduction link

https://github.com/E-jarod/vue3-test.git

Steps to reproduce

Hello, I have simply created a new Vue 3.0.0 (vue create vue3-test) project with the following preset :
~/.vuerc

{
  ...
  "presets": {
    "personal-basic-vue3": {
      "useConfigFiles": true,
      "plugins": {
        "@vue/cli-plugin-babel": {},
        "@vue/cli-plugin-typescript": {
          "classComponent": true,
          "useTsWithBabel": true
        },
        "@vue/cli-plugin-router": {
          "historyMode": true
        },
        "@vue/cli-plugin-eslint": {
          "config": "prettier",
          "lintOn": [
            "save",
            "commit"
          ]
        },
        "@vue/cli-plugin-unit-jest": {},
        "@vue/cli-plugin-e2e-cypress": {}
      },
      "vueVersion": "3",
      "cssPreprocessor": "dart-sass"
    }
  }
}

I come from angular and I am new to Vue. Everything else works fine, but not the jest unit test.

You can see on my github repo.

What is expected?

The jest test should at least works, because it is the starter project.

What is actually happening?

And when I run :

yarn test:unit
# or
npm run test:unit

I get the following Error

❯ y test:unit
yarn run v1.22.5
$ vue-cli-service test:unit
 FAIL  tests/unit/example.spec.ts
  ● Test suite failed to run

    TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    tests/unit/example.spec.ts:7:34 - error TS2769: No overload matches this call.
      The last overload gave the following error.
        Argument of type 'DefineComponent<{}, {}, {}, Record<string, ComputedGetter<any> | WritableComputedOptions<any>>, MethodOptions, ComponentOptionsMixin, ... 5 more ..., {}>' is not assignable to parameter of type 'ComponentOptionsWithObjectProps<readonly string[] | Readonly<ComponentObjectPropsOptions<Record<string, unknown>>>, {}, {}, Record<string, ComputedGetter<any> | WritableComputedOptions<...>>, ... 6 more ..., { ...; } | {}>'.
          Property 'props' is missing in type 'ComponentPublicInstanceConstructor<{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Pick<Readonly<{} & {}> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "key" | ... 8 more ... | "style">; ... 10 more ...; $watch(source: string | Function, cb: Function, options?: WatchOptions<...> | und...' but required in type '{ props: (readonly string[] & ThisType<void>) | (Readonly<ComponentObjectPropsOptions<Record<string, unknown>>> & ThisType<void>); }'.

    7     const wrapper = shallowMount(HelloWorld, {
                                       ~~~~~~~~~~

      node_modules/@vue/runtime-core/dist/runtime-core.d.ts:336:5
        336     props: PropsOptions & ThisType<void>;
                ~~~~~
        'props' is declared here.
      node_modules/@vue/test-utils/dist/mount.d.ts:36:25
        36 export declare function mount<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D, C extends ComputedOptions = {}, M extends Record<string, Function> = {}, E extends EmitsOptions = Record<string, any>, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, EE extends string = string>(componentOptions: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, E, Mixin, Extends, EE>, options?: MountingOptions<ExtractPropTypes<PropsOptions>, D>): VueWrapper<ComponentPublicInstance<ExtractPropTypes<PropsOptions>, RawBindings, D, C, M, E, VNodeProps & ExtractPropTypes<PropsOptions>>>;
                                   ~~~~~
        The last overload is declared here.

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.526s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Can you detail why this is happening ?

@posva posva transferred this issue from vuejs/core Oct 16, 2020
@posva
Copy link
Member

posva commented Oct 16, 2020

@E-jarod moved to the correct repo although this looks more like a question than a bug report. We have a forum and a Discord chat to ask questions!
Leaving open because there seems to be something to fix on the initial scaffolding though

cexbrayat added a commit to cexbrayat/vue-cli that referenced this issue Oct 16, 2020
vuejs/core@6aa2256 intriduced a change in `DefineComponent` type, that results in a broken bare CLI app that would use VTU, as `mount` will not compile.

This relaxes the type definitation by using generic `any`.

Fixes vuejs#5974
@cexbrayat
Copy link
Member

cexbrayat commented Oct 16, 2020

Stumbled on this as well when upgrading to Vue 3.0.1 and this is indeed reproducible with a bare CLI app.

The root cause is Vue 3.0.1 changed the default value of props from any to {} which breaks VTU mount when using SFCs.

The workaround we used to update our applications was to change the default shim to be DefineComponent<any, any, any>. I opened a PR if this is the way to go, but maybe it would be better to revert vuejs/core@6aa2256

See #5975

edit: I also opened a repro in vtu-next in case we manage to fix it there vuejs/test-utils#223

@E-jarod
Copy link
Author

E-jarod commented Oct 16, 2020

So, if I understand, it's a problem in the core of Vue ? (not in my code ?)
And I need to upgrade from vue from 3.0.0 to 3.0.1 ?

@FossPrime
Copy link
Contributor

FossPrime commented Oct 16, 2020

@E-jarod it's a problem in your Typescript shim, that was generated by the cli code... just add the line const component: DefineComponent<any, any, any> it will disable the type check and allow testing to proceed.

@E-jarod
Copy link
Author

E-jarod commented Oct 16, 2020

@rayfoss Okay and in which fie ?

@cexbrayat
Copy link
Member

Yes its something we need to fix on Vue side (either in vue-next, the CLI or vue-test-utils-next)

You can workaround it for now by updating the shim like I did in the PR

@E-jarod
Copy link
Author

E-jarod commented Oct 16, 2020

@cexbrayat sorry, I don't get how to modify :

- PropsOrPropOptions = any,
- RawBindings = any,
- D = any,
+ PropsOrPropOptions = {},
+ RawBindings = {},
+ D = {},

apiDefineComponent.ts is a non-compiled version of vue isn't it ?

@FossPrime
Copy link
Contributor

@cexbrayat sorry, I don't get how to modify :

- PropsOrPropOptions = any,
- RawBindings = any,
- D = any,
+ PropsOrPropOptions = {},
+ RawBindings = {},
+ D = {},

apiDefineComponent.ts is a non-compiled version of vue isn't it ?

make this your src/shims-vue.d.ts

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<any, any, any>
  export default component
}

@E-jarod
Copy link
Author

E-jarod commented Oct 16, 2020

make this your src/shims-vue.d.ts

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<any, any, any>
  export default component
}

I get the same error ;(

@cexbrayat
Copy link
Member

Try to clear the cash: yarn test:unit --clear-cache and rerun the test

@E-jarod
Copy link
Author

E-jarod commented Oct 17, 2020

@cexbrayat I still have the same error message

@cexbrayat
Copy link
Member

@E-jarod I'm not sure I can help then, as this fixes it in our various Vue 3 apps and in a bare CLI project.
You can try to reproduce and create a github repo so I can take another look.
But we should be able to fix it soon, either in the CLI or in VTU (@pikax has a patch almost ready)

@E-jarod
Copy link
Author

E-jarod commented Oct 17, 2020

Okay, I will wait then until the patch 👍

@juan267
Copy link

juan267 commented Oct 17, 2020

I think this only happens when you start the project using vue-class-component package. In that case the above proposed fix does fix the TS overload issue but you then get this when running the test:

  console.warn node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:40
    [Vue warn]: Property "msg" was accessed during render but is not defined on instance. 
      at <Anonymous msg="blah" ref="VTU_COMPONENT" > 
      at <VTUROOT>

I guess this might be an issue between vue-class-component and vue-test-utils

cexbrayat added a commit to cexbrayat/vue-cli that referenced this issue Oct 18, 2020
vuejs/core@6aa2256 intriduced a change in `DefineComponent` type, that results in a broken bare CLI app that would use VTU, as `mount` will not compile.

This relaxes the type definitation by using generic `any`.

Fixes vuejs#5974
@alperkay
Copy link

I think this only happens when you start the project using vue-class-component package. In that case the above proposed fix does fix the TS overload issue but you then get this when running the test:

  console.warn node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:40
    [Vue warn]: Property "msg" was accessed during render but is not defined on instance. 
      at <Anonymous msg="blah" ref="VTU_COMPONENT" > 
      at <VTUROOT>

I guess this might be an issue between vue-class-component and vue-test-utils

I confirm that I have this issue and above proposed fixes also didn't help me.

@taylorjdawson
Copy link

I have the exact same issue as @alperkay and @juan267. This should be reopened.

@DawnEve
Copy link

DawnEve commented Apr 23, 2021

vue.global-3.0.11.js

html:
<a v-bind:[attributeName2]="url"> attributeName2={{attributeName2}} </a><br>
<a v-on:[eventName3]="doSth"> eventName3={{eventName3}} </a>


js:
var vm=Vue.createApp({
	data(){
		return{
			url: "https://www.google.com",
			attributeName2: "href",
			eventName3:"click",
		}
	},
	
	methods:{
		doSth(){
			alert("You clicked me!")
		}
	}
}).mount("#app")

the same error:

page:
<a> attributeName2=href</a>
<br>
<a> eventName3=click</a>


# console:
[Vue warn]: Property "attributename2" was accessed during render but is not defined on instance. 
[Vue warn]: Property "eventname3" was accessed during render but is not defined on instance.

@vfioox
Copy link

vfioox commented Apr 10, 2022

This is still happening, in another scenario as well. I use Vue 3 with composition API.

declare module '*.vue' {
  import type { DefineComponent } from 'vue';
  const component: DefineComponent<{}, {}, any>;
  export default component;
}

declare module 'vue/types/vue' {
  import { Router, RouteRecord } from 'vue-router';
  import { Store } from 'vuex';
  interface VueConstructor {
    $router: Router;
    $route: RouteRecord;
    $store: Store<any>;
    $api: any;
  }
}

I tried multiple arrangements here, like moving the interface into any type argument of that DefineComponent at the bottom, tried any, any, any. Really tried everything I could, restarted lint server every time. This one is a hard one.

@steven87vt
Copy link

vue3 jest tests throwing the same error except it was my fault as to why.

threw me for a loop when I first got started with vue3 and jest mocking. if you so happen to pass in computed properties into the mount option, you have to define all of them otherwise they are set to undefined. vue3 changed from a merge strategy in v2 to a replace all strategy it seems.

defineComponent({
  name: 'Something',
  computed: {
   a (): boolean {
    return true
   },
  b (): boolean {
    return false
  }
})
it('something' () => {
  const computed: { a: () => boolean; } = {
    a () {
      return false
    }
  }
  
  const wrapper = shallowMount(Something, {computed})
  wrapper.vm.b // b is undefined <~ root cause
  wrapper.vm.a // false
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants