1.0.0-beta.16
https://codesandbox.io/s/6lm4248qjr
In reproduction link, 1.0.0-beta.12 version is selected on which test is passing. Upgrading to any version after 1.0.0-beta.12 causes test to fail with error Cannot read property '$options' of undefined when setData is invoked.
Test should pass on later/latest versions as well.
Test is failing on vue-test-utils latest versions(after 1.0.0-beta.12 )
Since this worked fine on version 1.0.0-beta.12, i assume this bug could be side effect of PR https://github.com/vuejs/vue-test-utils/pull/438 merged in version 1.0.0-beta.13, as all ElementUI components used in the sample reproduction link are not functional components, so it should work ok on latest version as well. Links to component's used in this sample are below for reference:
https://github.com/ElemeFE/element/blob/v2.3.8/packages/form/src/form.vue
https://github.com/ElemeFE/element/blob/v2.3.8/packages/form/src/form-item.vue
https://github.com/ElemeFE/element/blob/v2.3.8/packages/input/src/input.vue
Thanks for the bug report.
This is a problem with how we have implemented synchronous updating. There's a PR open to fix this by adding an async option to Vue—https://github.com/vuejs/vue/pull/8240.
For the moment, the workaround is to set the sync mounting option to false and use Vue.nextTick to await DOM updates:
test('use Vue.nextTick', (done) => {
const wrapper = mount(TestComponent, { sync: false })
wrapper.trigger('click')
Vue.nextTick(() => {
expect(wrapper.text()).toBe('updated')
done()
})
})
Thank you providing the update on this and suggesting workaround. 👍
I was facing this issue and when i realized a fix was provided, I updated from 1.0.0-beta.16 to 1.0.0-beta.18 and all my tests are breaking. I have a feeling a lot changed especially with the way stubbing is done. Can you please help clarify. Thanks
There is a bug where stubs and mocks aren't applied correctly to extended components, including the class component. The fix will be released soon.
The issue here is still unresolved.
I have a very similar case, I don't know, if it should be a separate issue:
When upgrading from 1.0.0-beta.17 (up to 1.0.0-beta.20 I tried), all my components that use vuelidate are unable to reach data(). If I try and test if the initial values are correctly set, I get an error message: Cannot read property 'validations' of undefined.
If I use it like this:
const data = vm.$options.data
expect(data().someValue).toEqual('value')
then I get Cannot read property '$options' of undefined.
If I change to
expect(vm.$options.data().someValue).toEqual('value')
then the error message changes to the one above.
Both worked under 1.0.0-beta.17, and vuelidate didn't change since.
Any ideas?
Sorry about this. Can you post a minimal reproduction?
Steps to reproduce
package.json
{
"name": "vue-test-utils-jest-example",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "Edd Yerburgh <[email protected]>",
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src test",
"lint:fix": "npm run lint --fix",
"unit": "jest"
},
"dependencies": {
"@vue/test-utils": "^1.0.0-beta.20",
"element-ui": "^2.4.2",
"vue": "^2.5.16",
"vue-router": "^2.6.0"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.1.1",
"babel-jest": "^23.2.0",
"babel-loader": "^7.1.1",
"babel-plugin-module-resolver": "^2.7.1",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"connect-history-api-fallback": "^1.3.0",
"css-loader": "^0.28.0",
"cssnano": "^3.10.0",
"eslint": "^3.19.0",
"eslint-config-standard": "^6.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-html": "^3.0.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^2.0.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.11.1",
"friendly-errors-webpack-plugin": "^1.1.3",
"html-webpack-plugin": "^2.28.0",
"http-proxy-middleware": "^0.17.3",
"jest": "^23.2.0",
"jest-serializer-vue": "^2.0.2",
"opn": "^5.1.0",
"optimize-css-assets-webpack-plugin": "^2.0.0",
"ora": "^1.2.0",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"url-loader": "^0.5.8",
"vue-jest": "^2.6.0",
"vue-loader": "^12.1.0",
"vue-server-renderer": "^2.5.16",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.16",
"webpack": "^2.6.1",
"webpack-bundle-analyzer": "^2.2.1",
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"snapshotSerializers": [
"<rootDir>/node_modules/jest-serializer-vue"
]
}
}
Component with ElementUI dropdown and table
<template>
<div>
<el-select v-model="value" placeholder="Select">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<br/>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="Date"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="Name"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="Address">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "dropdown-sample",
data() {
return {
options: [
{
value: "Option1",
label: "Option1"
},
{
value: "Option2",
label: "Option2"
}
],
value: "",
tableData: [
{
date: "2016-05-03",
name: "Tom",
address: "No. 189, Grove St, Los Angeles"
},
{
date: "2016-05-02",
name: "Tom",
address: "No. 189, Grove St, Los Angeles"
}
]
}
}
}
</script>
Test
import { mount, createLocalVue } from '@vue/test-utils'
import { createRenderer } from 'vue-server-renderer'
import ElementUI from 'element-ui'
import DropDownSample from '@/components/DropDownSample.vue'
let localVue = createLocalVue()
localVue.use(ElementUI)
describe('DropDownSample.vue', () => {
it('displays default message', () => {
const wrapper = mount(DropDownSample, { localVue })
const renderer = createRenderer()
renderer.renderToString(wrapper.vm, (err, str) => {
if (err) throw new Error(err)
expect(str).toMatchSnapshot()
})
})
})
Test Results
yarn unit
yarn run v1.7.0
warning package.json: No license field
$ jest
PASS src/components/__tests__/DropDownSample.spec.js
DropDownSample.vue
√ displays default message (140ms)
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Error in callback for watcher "options": "TypeError: Cannot read property 'querySelectorAll' of undefined"
found in
---> <ElSelect>
<DropdownSample>
<Root>
console.error node_modules/vue/dist/vue.runtime.common.js:1739
TypeError: Cannot read property 'querySelectorAll' of undefined
at VueComponent.options (C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:8567:29)
at Watcher.run (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:3231:19)
at flushSchedulerQueue (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:2979:13)
at Array.<anonymous> (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1835:12)
at flushCallbacks (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1756:14)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Error in nextTick: "TypeError: Cannot read property 'clientWidth' of undefined"
console.error node_modules/vue/dist/vue.runtime.common.js:1739
TypeError: Cannot read property 'clientWidth' of undefined
at TableLayout.updateColumnsWidth (C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:11450:36)
at VueComponent.updateScrollY (C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:10269:19)
at C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:10829:26
at Array.<anonymous> (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1835:12)
at flushCallbacks (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1756:14)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 2.822s, estimated 3s
Ran all test suites.
Done in 3.89s.
Any idea about this?
Can you try setting sync to false and use Vue.nextTick to await DOM updates:
test('use Vue.nextTick', (done) => {
const wrapper = mount(TestComponent, { sync: false })
wrapper.trigger('click')
Vue.nextTick(() => {
expect(wrapper.text()).toBe('updated')
done()
})
})
I changed the test as below (sync is set to false and Vue.nextTick is used)
But the test results is still the same.
import Vue from "vue"
import { mount, createLocalVue } from "@vue/test-utils"
import { createRenderer } from "vue-server-renderer"
import ElementUI from "element-ui"
import DropDownSample from "@/components/DropDownSample.vue"
let localVue = createLocalVue()
localVue.use(ElementUI)
describe("DropDownSample.vue", () => {
it("displays default message", () => {
const wrapper = mount(DropDownSample, { sync: false, localVue })
const renderer = createRenderer()
Vue.nextTick(() => {
renderer.renderToString(wrapper.vm, (err, str) => {
if (err) throw new Error(err)
expect(str).toMatchSnapshot()
})
})
})
})
Test Results
PS C:\Projects\Issues\vue-unit-test-starter> yarn unit
yarn run v1.7.0
warning package.json: No license field
$ jest
PASS src/components/__tests__/DropDownSample.spec.js
DropDownSample.vue
√ displays default message (265ms)
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Error in callback for watcher "options": "TypeError: Cannot read property 'querySelectorAll' of undefined"
found in
---> <ElSelect>
<DropdownSample>
<Root>
console.error node_modules/vue/dist/vue.runtime.common.js:1739
TypeError: Cannot read property 'querySelectorAll' of undefined
at VueComponent.options (C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:8567:29)
at Watcher.run (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:3231:19)
at flushSchedulerQueue (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:2979:13)
at Array.<anonymous> (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1835:12)
at flushCallbacks (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1756:14)
at <anonymous>
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Error in nextTick: "TypeError: Cannot read property 'clientWidth' of undefined"
console.error node_modules/vue/dist/vue.runtime.common.js:1739
TypeError: Cannot read property 'clientWidth' of undefined
at TableLayout.updateColumnsWidth (C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:11450:36)
at VueComponent.updateScrollY (C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:10269:19)
at C:\Projects\Issues\vue-unit-test-starter\node_modules\element-ui\lib\element-ui.common.js:10829:26
at Array.<anonymous> (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1835:12)
at flushCallbacks (C:\Projects\Issues\vue-unit-test-starter\node_modules\vue\dist\vue.runtime.common.js:1756:14)
at <anonymous>
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 4.575s
Ran all test suites.
Done in 5.87s.
Can you create a full minimal reproduction that I can run (either on code sandbox or GitHub). Please use the least amount of code possible to reproduce the issue. Then open a new issue with the reproduction.
@ChandruCR maybe you should change Vue.nextTick to localVue.nextTick
@BartekZienkiewicz
I get same warnings for localVue and Vue.
@eddyerburgh
These warnings are thrown for Jest Snapshots tests only.
Other tests succeed without any warning.
I will create a new issue for this. #770
submitted new issue (#795)
The reproduction issue is fixed with the latest version of element-ui—https://codesandbox.io/s/3rvrqrv2vq
Most helpful comment
Thanks for the bug report.
This is a problem with how we have implemented synchronous updating. There's a PR open to fix this by adding an async option to Vue—https://github.com/vuejs/vue/pull/8240.
For the moment, the workaround is to set the
syncmounting option to false and use Vue.nextTick to await DOM updates: