Description
When providing an object, its properties are correctly injected into the (shallow)mounted component.
However, when changing the properties, computed properties of my component do not notice the change and do not recompute. I am using the Vue-Property-Decorator InjectReactive annotation, which automatically wraps annotated attributes into a "reactiveInject" object.
Relevant versions are VueJs 2.7.10, vue-test-utils 1.3.0, vue-property-decorator 9.1.2
Example code
@Component
export default class MyComponent extends Vue {
@InjectReactive someValue!: string | null
get computedProperty(): string {
return this.someValue
}
})
const localVue = createLocalVue()
describe('test', () => {
let wrapper
let reativeInject
beforeEach(() => {
reactiveInject = { someValue: 'hello' }
wrapper = shallowMount(MyComponent, {
provide: () => {
return { __reactiveInject__: reactiveInject }
},
localVue
}
})
it('initial injection', () => {
expect(wrapper.vm.computedProperty).toEqual('hello') // TEST PASSES
})
it('changed value', async () => {
reactiveInject.someValue = 'goodbye'
await wrapper.vm.nextTick()
expect(wrapper.vm.computedProperty).toEqual('goodbye') // TEST FAILS, value is still 'hello'
})
})
Expected behaviour
Both tests should be green
Actual behaviour
The second test fails, as the value is still 'hello'. The computed property is not recomputed. When actually using the code in production it works as expected.
Possible Solution
I can only get the second test to pass with injection if I mount the component again with a different value. However, this is a lot of overhead and doesn't allow me to test that my component reacts to changes correctly.
Alternatively, I can choose not to use provide when mounting and instead pass the value as data. However, this means that the test doesn't show the correct usage of the InjectReactive annotation. The test would even pass if I forget to use the annotation.
I've tried multiple ways to provide the information in my test, including a more elaborate setup for the provided data:
let someValue
let reactiveData
beforeEach(() => {
someValue = 'hello'
})
...
provide() {
reactiveData = {}
Object.defineProperty(reactiveData, 'someValue', {
enumerable: true,
get: () => someValue,
set: (newValue) => (someValue = newValue)
})
return {
__reactiveInject__: reactiveData
}
}
...
it('changed value', async () => {
reactiveData.someValue = 'goodbye'
await wrapper.vm.nextTick()
expect(wrapper.vm.computedProperty).toEqual('goodbye') // TEST FAILS, value is still 'hello'
})
Am I doing something wrong or is there a problem with the vue-test-utils?