1.0.0-beta.29
https://github.com/xavism/lazyloading-vue-test-utils
$ npm i
$ npm t
Then check the snapshots
Both snapshots (Parent and ParentLazy) are expected to be the same. shallowMount should stub the child components
ParentLazy's snapshot is rendering the Child component when using shallowMount, the child component in the snapshot is not stubbed
Related to a closed issue:
shallowMount will not stubs lazily registered components #959
https://github.com/vuejs/vue-test-utils/issues/959
It should be fixed but it's not working in my case.
Duplicate of #959
Reopened
Hi there, I was wondering if there's any update on this.. We have the exact same issue.
As I see in your Github you are using the Jest, lazy load (() => import) and of course NodeJS.
"Jest runs in Node, and thus requires ES modules to be transpiled to CommonJS modules.
If you use dynamic imports (import('some-file.js').then(module => ...)), you need to enable the dynamic-import-node plugin"
See Jest docs https://jestjs.io/docs/en/webpack.html#using-with-webpack-2
Solution:
Need to install the babel-plugin-dynamic-import-node (https://www.npmjs.com/package/babel-plugin-dynamic-import-node).
Or the import works only with "--experimental-modules" in NodeJS(current LTS https://nodejs.org/dist/latest-v12.x/docs/api/esm.html#esm_enabling).
// my .babelrc
{
"env": {
"test": {
"presets": [
["env", {
"targets": {
"node": "current"
}
}]
],
"plugins": ["dynamic-import-node"]
}
}
}
// my jest.config.js
module.exports = {
moduleFileExtensions: [
'js',
'json',
'vue'
],
'transform': {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
},
};
// my env:
1) Laravel v5.8.23;
2) main "devDependencies":
"jest": "^24.9.0",
"vue": "^2.5.17",
"vue-jest": "^3.0.5",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^6.26.3",
"babel-jest": "^24.9.0",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-preset-env": "^1.7.0",
"laravel-mix": 4.0.7,
3) the Docker image with NodeJS v8
I face a similar issue when using to dynamic components
Would a fix for this issue cover this use case as well?
As I see in your Github you are using the Jest, lazy load (() => import) and of course NodeJS.
"Jest runs in Node, and thus requires ES modules to be transpiled to CommonJS modules.
If you use dynamic imports (import('some-file.js').then(module => ...)), you need to enable the dynamic-import-node plugin"
See Jest docs https://jestjs.io/docs/en/webpack.html#using-with-webpack-2Solution:
Need to install the babel-plugin-dynamic-import-node (https://www.npmjs.com/package/babel-plugin-dynamic-import-node).
Or the import works only with "--experimental-modules" in NodeJS(current LTS https://nodejs.org/dist/latest-v12.x/docs/api/esm.html#esm_enabling).// my .babelrc
{ "env": { "test": { "presets": [ ["env", { "targets": { "node": "current" } }] ], "plugins": ["dynamic-import-node"] } } }// my jest.config.js
module.exports = { moduleFileExtensions: [ 'js', 'json', 'vue' ], 'transform': { '^.+\\.js$': '<rootDir>/node_modules/babel-jest', '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest' }, };// my env:
- Laravel v5.8.23;
- main "devDependencies":
"jest": "^24.9.0","vue": "^2.5.17",
"vue-jest": "^3.0.5",
"@vue/test-utils": "^1.0.0-beta.29","babel-core": "^6.26.3",
"babel-jest": "^24.9.0",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-preset-env": "^1.7.0","laravel-mix": 4.0.7,
- the Docker image with NodeJS v8
I've added your solution to the reproduction package ( https://github.com/xavism/lazyloading-vue-test-utils) and it is still not working.
Could you tell me what am I doing wrong?
have you found a solution for that?
have you found a solution for that?
Unfortunately no :(
still no update on this?
So I think the reason this happens is because the way shallowMount works is by overriding this.$createElement to stub out components before they are mounted. Since the import is async (lazy), the component is loaded after all the stubbing has occurred.
If my guess is correct, this is not something we can fix without a major rework of the library. The only suggested I can come up with to make your snapshots match is to use mount. I don't think this is so bad; using mount will make your snapshot more closely resemble your production code.
If anyone wants to dig into this one, I can provide some guidance or even pair with you on it.
As a less-than-ideal workaround, you can explicitly provide stubs for async components.
I am having the same issue, I lazy load my components, and shallowMount behave like mount, but mount itself doesn't really work.
I need to explicitly setup the stubs for my child component in shallowMount, and then it works properly.
If instead I try to use mount, the stub is not be consider at all.
I created a factory function to switch easily between mount and shallow, but mount just doesn't work.
Call me crazy but if you are loading a component why would you want to use shallowMount? That will stub out your async component (now you can't test it, because it's stubbed out).
Hi @lmiller1990 , first of all thanks for your time.
In my case, I want to use shallowMount even when I'm lazy-loading my child components because I don´t want to add to my localVue the dependencies this child components needs.
Does it make sense?
I see, makes sense. Time for a deep dive into the dark depths of shallowMount!
Since shallowMount() behaves like mount(). I'm thinking about consider this problem in the opposite way: make mount() behaves like shallowMount.
For example, Parent component lazy load Child component
<template>
<div>
Parent
<Child />
</div>
</template>
<script>
export default {
components: {
Child: () => import('./Child')
}
}
</script>
Step 1. Change shallowMount into mount in unit tests
const wrapper = mount(Parent)
Step 2. Add stubs option to mount
const wrapper = mount(Parent, {
stubs: {
Child: true
}
})
The child component will be mount as <child-stub></child-stub> like we are using shallowMount.
^ seems like a good work around!
@lmiller1990 I wonder that if mount can make child stub as <child-stub> exactly like the same thing shallowMount would do. Why shallowMount can't do it? Is there anything blocks this process? Would it be possible to let shallowMount be improved to compatible with dynamic import if we found the things block the process?
I have no idea why this happens, I took a look but didn't have much luck fixing it. I would probably need to spend more time on it.
If you would like to try figuring it out I can try to help out. I personally recommend against using shallowMount - what is your use-case that prevents you from using mount?
I have tried hacking this as well many times, alas got nowhere... I think this is finally fixed in VTU 2 though 😄
@dobromir-hristov Do we have a confirmation that it's actually fixed in Vue Test Utils 2 / Vue 3?
I just cloned and updated the repo linked in the first post. I used Vue 3, VTU v2 and ts-jest v25. The first two tests passed fine, I had to update the snapshots with -u and then everything was green.
So yep, seems fine. This is because the shallow mounting is (kind of) baked into Vue core now via a transformVNodeArgs function.
Of course that is in a different codebase using different dependencies - I do not expect this issue will be fixed in VTU v1 (for Vue 2) at this point.
Most helpful comment
Since
shallowMount()behaves likemount(). I'm thinking about consider this problem in the opposite way: makemount()behaves likeshallowMount.For example,
Parentcomponent lazy loadChildcomponentStep 1. Change
shallowMountintomountin unit testsStep 2. Add
stubsoption tomountThe child component will be mount as
<child-stub></child-stub>like we are usingshallowMount.