I am upgrading a Vue 2 component library to Vue 3. I have upgraded all the packages in the project, and made some necessary changes to get the code to compile. The components work as expected in a demo application.
Unfortunately, when I run the jest unit tests, I get a bunch of Cannot call [something] on an empty DOMWrapper
. I found that jest does not seem to recognize the template definition in the <template></template>
tag in the .vue file. However, if I define the template as a component property like:
export default {
template: `<div class="component__wrapper">
...
</div>`,
name: 'Component',
...
the tests run fine and all pass.
Am I missing some crucial tidbit in the jest.config.json
?
These are my relevant package versions:
"@types/jest": "^29.5.10",
"@vue/test-utils": "^2.4.3",
"@vue/vue3-jest": "^29.2.6",
"babel-jest": "^29.7.0",
"babel-loader": "^9.1.3",
"babel-preset-vue": "^2.0.2",
"ts-jest": "^29.1.1",
"typescript": "^5.3.2",
"vue": "^3.3.9",
"vue-loader": "^17.3.1",
"vue-style-loader": "^4.1.3",
and my jest.config.json looks like:
{
"preset": "ts-jest",
"testEnvironment": "jsdom",
"testEnvironmentOptions": {
"customExportConditions": ["node", "node-addons"]
},
"rootDir": "..",
"setupFiles": [
"<rootDir>/jest/setup.js"
],
"transform": {
"^.+\\.jsx?$": "babel-jest",
"^.+\\.tsx?$": "ts-jest",
"^.*\\.vue$": "@vue/vue3-jest"
},
"transformIgnorePatterns": [
"/node_modules/(?!(@storybook/.*\\.vue$))"
],
"testRegex": "/__tests__/.*\\.spec\\.(ts|js)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"vue",
"json"
],
"moduleNameMapper": {
"\\.(jpg|png|gif|svg)$": "<rootDir>/jest/image-mocks.js"
},
"snapshotSerializers": [
"jest-serializer-vue"
],
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.ts"
],
"coveragePathIgnorePatterns": [
".d.ts$",
".stories.ts$",
"index.ts$",
"/__tests__/",
"/stories/",
"/types/"
],
"coverageReporters": [
"json",
"lcov",
"text",
"html"
],
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
},
"clearMocks": true
}
Been pulling my hair out - if anyone has any ideas, I would appreciate it.
In case anyone else comes to this question, the answer came from a coworker of mine. The solution was to change the script in the .vue
file from:
<script>module.exports = require('./RadioButton.ts')</script>
to
<script lang="ts">
import RadioButton from "./RadioButton";
export default RadioButton;
</script>
Unfortunately, not really sure why that worked. If anyone has thoughts, feel free to comment.