Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
With the Vue Test Utils library, we can write and run unit tests for Vue apps easily.
In this article, we’ll look at how to write unit tests with the Vue Test Utils library.
Mocking Transitions
We can test components with transitions the same way we test other components.
All we have to do is to set the reactive properties to the value we want.
For example, we can write:
import { mount } from '@vue/test-utils'
const Foo = {
template: `
<div>
<transition>
<p v-if="show">Foo</p>
</transition>
</div>
`,
data() {
return {
show: true
}
}
}
describe('Foo', () => {
it('renders bar for foo prop', async () => {
const wrapper = mount(Foo)
expect(wrapper.text()).toMatch(/Foo/)
await wrapper.setData({
show: false
})
expect(wrapper.text()).not.toMatch(/Foo/)
})
})
We call mount
to mount the Foo
component.
Then we check what’s displayed before we set the show
reactive property to false
.
Then we call setData
to set show
to false
.
Then we check the pattern of the content displayed with the text
method to return the rendered text and the toMatch
method to check whether the content matches the given regex pattern.
We can also stub the transitions with the transitionStub
helper:
import { mount } from '@vue/test-utils'
const Foo = {
template: `
<div>
<transition>
<p v-if="show">Foo</p>
</transition>
</div>
`,
data() {
return {
show: true
}
}
}
const transitionStub = () => ({
render(h) {
return this.$options._renderChildren
}
})
describe('Foo', () => {
it('renders bar for foo prop', async () => {
const wrapper = mount(Foo, {
stubs: {
transition: transitionStub()
}
})
expect(wrapper.text()).toMatch(/Foo/)
await wrapper.setData({
show: false
})
expect(wrapper.text()).not.toMatch(/Foo/)
})
})
transitionStub
is just a function that returns an object with the render
method to simulate rendering the transitions.
We can also avoid using setData
if we mount our component and set the reactive properties’ values when we mount it:
import { mount } from '@vue/test-utils'
const Foo = {
template: `
<div>
<transition>
<p v-if="show">Foo</p>
</transition>
</div>
`,
data() {
return {
show: true
}
}
}
test('should render Foo', async () => {
const wrapper = mount(Foo, {
data() {
return {
show: true
}
}
})
expect(wrapper.text()).toMatch(/Foo/)
})
test('should not render Foo', async () => {
const wrapper = mount(Foo, {
data() {
return {
show: false
}
}
})
expect(wrapper.text()).not.toMatch(/Foo/)
})
Applying Global Plugins and Mixins
If we want to apply global plugins, then we have to use the createLocalVue
to return a mocked version of the Vue
constructor.
This way, we can control when the global plugin is applied.
For example, we can write:
import { createLocalVue, mount } from '@vue/test-utils'
const localVue = createLocalVue()
const MyPlugin = {};
MyPlugin.install = function (Vue, options) {
Vue.prototype.fooMethod = function () {
this.foo = 'bar';
}
}
localVue.use(MyPlugin);
const Foo = {
template: `
<div>
<p>{{foo}}</p>
</div>
`,
data() {
return {
foo: ''
}
}
}
test('should render bar', async () => {
const wrapper = mount(Foo, {
localVue
})
await wrapper.vm.fooMethod();
expect(wrapper.text()).toContain('bar')
})
We call the createLocalVue
function to create a mock version of the Vue
constructor.
Then we create our plugin by defining the MyPlugin
object and adding the fooMethod
instance method to our plugin.
Next, we call localVue.use(MyPlugin)
so we can add our plugin with we mount
the Foo
component.
Then in our test, we set the localVue
property in the object in the 2nd argument of mount
.
And we call our fooMethod
to run the test.
Finally, we check if the text is rendered.
Conclusion
We can mock transitions and plugins so that we can do test with plugins.