I'm writing some tests using vue-test-util
for a component I've made. I have boiled my code down to the actual problem.
The component is of the form:
<template>
<inner-component>
</template>
<script>
export default {
name: 'MyList'
}
</script>
and my inner component looks something like this:
<template>
<div v-if="open">Some stuff</div>
</template>
<script>
export default {
name: 'InnerComponent',
props: {
open: false,
}
}
</script>
Now the test I'm writing is testing for the existence of the div
in the inner-component
when the open
prop is set to true
, but it is set to false
by default. I need a way to set the prop of this child component before I test it.
My test:
import { createLocalVue, mount } from '@vue/test-utils'
import MyList from '@/components/MyList.vue'
describe('My Test', () => {
const localVue = createLocalVue()
const wrapper = mount(MyList)
it('Tests', () => {
// need to set the prop here
expect(wrapper.find('div').exists()).toBeTruthy()
}
}
I can use:
wrapper.vm.$children[0].$options.propsData.open = true
Which does appear to set the prop, but my tests still come up as receiving false.
I can change the component so the default is true and then my tests pass so I don't think it's the way I'm checking.
If anyone can spot why this isn't working or knows a better way to come at it, please let me know!
According to the guide:
vm.$options
The instantiation options used for the current Vue instance.
So, $options
is not what we write in props
.
Use $props
to set property for a child component:
wrapper.vm.$children[0].$props.open = true
But this way leads to the warning:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
So, let's follow the advice and bind property of the child component with data of the parent component. Here I bind it with isOpen
variable:
<template>
<inner-component :open='isOpen'></inner-component>
</template>
<script>
import InnerComponent from '@/components/InnerComponent.vue'
export default {
name: 'MyList',
data() {
return {
isOpen: false
}
},
components:{InnerComponent}
}
</script>
Then in your test, you can just change the value of isOpen
when you want to change the value of open
property in the child component:
wrapper.setData({isOpen:true})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With