Unit Test Vue Apps with Vue Test Utils — Transitions and Plugin Tests
Tags: webdev, testing, javascript, vue
Published: 2021-01-23 02:10:36

**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.