Reputation: 2053
I use an instance of a class as a tool in one of my components. This component watches for changes in the class instance. However I fail at writing a test for that watcher.
I tried using jest.fn
, spyOn
and a setData
, but none of these worked.
The class looks like this:
export default class myTool {
constructor () {
this._myData = null
}
get myData () {
return this._myData
}
set myData (updatedMyData) {
this._myData = updatedMyData
}
}
And the component:
import myTool from '@/utils/myTool'
export default {
...
data() {
return {
myTool: null
}
},
methods: {
handleMyDataUpdate(updatedMyData) {
// do something
}
},
mounted() {
this.$watch('myTool.myData', (updatedMyData) => {
this.handleMyDataUpdate(updatedMyData)
})
this.myTool = new myTool()
}
...
}
jest.fn
:test:
it('should call handleMyDataUpdate on myData update.', () => {
const wrapper = mountComponent()
const handleMyDataUpdate = jest.fn()
wrapper.setMethods({ handleMyDataUpdate })
wrapper.vm.myTool.myData = 5
expect(handleMyDataUpdate).toBeCalled()
})
spyOn
:test:
it('should call handleMyDataUpdate on myData update.', () => {
const wrapper = mountComponent()
const spy = jest.spyOn(wrapper.vm, 'handleMyDataUpdate')
wrapper.vm.myTool.myData = 5
expect(spy).toBeCalled();
}
setData
:test:
it('should call handleMyDataUpdate on myData update.', () => {
const wrapper = mountComponent()
const handleMyDataUpdate = jest.fn()
wrapper.setMethods({ handleMyDataUpdate })
wrapper.setData({
myTool: {
myData: 5
}
})
expect(handleMyDataUpdate).toBeCalled()
}
Result: the 3 things I tried always fail with the following reason: Expected mock function to have been called.
, whether I comment the line where myData
is updated or not.
I tried wrapping the expect
line within a $nextTick
, but it doesn't work either:
wrapper.vm.$nextTick(() => {
// expectation
done()
})
The following error outputs and the test is always considered as "passed", whereas it should be "failed":
console.error node_modules/vue/dist/vue.runtime.common.js:1739
{ Error: expect(jest.fn()).toBeCalled()
Looking at line 1739 of vue.runtime.common.js
didn't help.
So how do I do to test my watcher?
Upvotes: 2
Views: 571
Reputation: 138226
The issue is your _myData
in the myTool
class is initially undefined
, so it's not reactive. To resolve the issue, initialize _myData
in myTool
's constructor:
class myTool {
constructor() {
this._myData = null
}
// ...
}
Then, your "1st attempt" test should pass successfully.
Upvotes: 1