Unit Test Vue Apps with Vue Test Utils — Child Components and Reactive Properties
Tags: vue, webdev, programming, javascript
Published: 2021-01-23 02:09:04

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

### Emitting Event from Child Component

We can check for events that are emitted in a child component.

To do that, we call `mount` to mount the parent component with the child component.

Then we can emit the event we want on the child:

```
import { mount } from '@vue/test-utils'

const ChildComponent = {
  template: `
    <div>
      <p>child</p>
    </div>
  `,
}

const ParentComponent = {
  template: `
    <div>
      <child-component @custom="onCustom" />
      <p id='emitted' v-if="emitted">emitted</p>
    </div>
  `,
  data() {
    return { emitted: false }
  },
  methods: {
    onCustom() {
      this.emitted = true
    }
  },
  components: {
    ChildComponent
  }
}

describe('ParentComponent', () => {
  it('shows emitted when child-component emits custom event', async () => {
    const wrapper = mount(ParentComponent)
    await wrapper.findComponent(ChildComponent).vm.$emit('custom')
    expect(wrapper.find('#emitted').text()).toContain('emitted')
  })
})
```

To mount the child component of `ParentComponent` with the `ParentComponent` , we call the `mount` method.

The `findComponent` method has `ChildComponent` as the argument so that we can use the returned component wrapper to emit the `custom` event with the `$emit` method.

Then to check if the ‘emitted’ text is displayed, we call the `find` method to check if it has the `'emitted'` string.

### Manipulating Component State

We can manipulate component state with the `setData` or `setProps` method.

For example, we can write:

```
import { mount } from '@vue/test-utils'

const Counter = {
  template: `
    <div>
      <p>{{count}}</p>
    </div>
  `,
  data() {
    return { count: 0 }
  },
}

describe('Counter', () => {
  it('renders 10 for count', async () => {
    const wrapper = mount(Counter)
    await wrapper.setData({ count: 10 })
    expect(wrapper.find('p').text()).toContain(10)
  })
})
```

to call the `setData` method with the data we want to set.

The key is the key of a reactive property and the value is its value.

To set props, we can use the `setProps` method:

```
import { mount } from '@vue/test-utils'

const Foo = {
  template: `
    <div>
      <p>{{foo}}</p>
    </div>
  `,
  props: ['foo']
}

describe('Foo', () => {
  it('renders bar for foo prop', async () => {
    const wrapper = mount(Foo)
    await wrapper.setProps({ foo: 'bar' })
    expect(wrapper.find('p').text()).toContain('bar')
  })
})
```

We call the `setProps` method to set the value of the `foo` prop to `'bar'` .

Then we check that if that is rendered in the last line of the test.

Props can also be set when we mount the component:

```
import { mount } from '@vue/test-utils'

const Foo = {
  template: `
    <div>
      <p>{{foo}}</p>
    </div>
  `,
  props: ['foo']
}

describe('Foo', () => {
  it('renders bar for foo prop', async () => {
    const wrapper = mount(Foo, {
      propsData: {
        foo: 'bar'
      }
    })
    expect(wrapper.find('p').text()).toContain('bar')
  })
})
```

The 2nd argument of the `mount` method takes the `propsData` property to let us mock the props.

### Conclusion

We can mock props and set values of reactive properties in our tests and test them.

Child component events can also be tested from the parent.