Unit Test Vue Apps with Vue Test Utils — Keyboard and Mouse Events
Tags: vue, testing, webdev, programming
Published: 2021-01-23 02:10:56

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

### Keyboard Event Tests

We can test keyboard events in our code.

For example, we can write:

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

const KEY_DOWN = 40
const KEY_UP = 38
const ESCAPE = 27

const QuantityComponent = {
  template: `
    <div>
      <input type="text" [@keydown](http://twitter.com/keydown "Twitter profile for @keydown").prevent="onKeydown" v-model="quantity" />
    </div>
  `,
  data() {
    return {
      quantity: 0
    }
  },
  methods: {
    increment() {
      this.quantity += 1
    },
    decrement() {
      this.quantity -= 1
    },
    clear() {
      this.quantity = 0
    },
    onKeydown(e) {
      if (e.keyCode === ESCAPE) {
        this.clear()
      }
      if (e.keyCode === KEY_DOWN) {
        this.decrement()
      }
      if (e.keyCode === KEY_UP) {
        this.increment()
      }
      if (e.key === 'a') {
        this.quantity = 10
      }
    }
  },
  watch: {
    quantity(newValue) {
      this.$emit('input', newValue)
    }
  }
}

describe('Key event tests', () => {
  it('Quantity is zero by default', () => {
    const wrapper = mount(QuantityComponent)
    expect(wrapper.vm.quantity).toBe(0)
  })

  it('Up arrow key increments quantity by 1', async () => {
    const wrapper = mount(QuantityComponent)
    await wrapper.find('input').trigger('keydown.up')
    expect(wrapper.vm.quantity).toBe(1)
  })

  it('Down arrow key decrements quantity by 1', async () => {
    const wrapper = mount(QuantityComponent)
    wrapper.vm.quantity = 2
    await wrapper.find('input').trigger('keydown.down')
    expect(wrapper.vm.quantity).toBe(1)
  })

  it('Escape sets quantity to 0', async () => {
    const wrapper = mount(QuantityComponent)
    wrapper.vm.quantity = 3
    await wrapper.find('input').trigger('keydown.esc')
    expect(wrapper.vm.quantity).toBe(0)
  })

  it('Magic character "a" sets quantity to 10', async () => {
    const wrapper = mount(QuantityComponent)
    await wrapper.find('input').trigger('keydown', {
      key: 'a'
    })
    expect(wrapper.vm.quantity).toBe(10)
  })
})
```

to trigger the keyboard events on each test.

The `QuantityComponent` has an input element that listens to the `keydown` event and updates the `quantity` accordingly.

The `onKeydown` method updates the `quantity` reactive property to set the value according to the key that’s pressed.

In our tests, we get the `input` element with the `find` method.

Then we call `trigger` to trigger various kinds of `keydown` events.

`keydown.up` simulates pressing the up arrow.

`keydown.up` simulates pressing the down arrow.

`keydown.up` simulates pressing the esc key.

The last test simulates pressing the `'a'` key.

Once we did that, we can check the `quantity` reactive property to get the final result.

### Testing Async Behavior

We can test async behavior by using the same principles as the previous example.

For example, we can write:

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

const Counter = {
  template: `
    <div>
      <button @click='count++'>add</button>
      <p>{{count}}</p>
    </div>
  `,
  data() {
    return {
      count: 0
    }
  },
}

describe('Counter tests', () => {
  it('count is set to 1 after click', async () => {
    const wrapper = mount(Counter)
    expect(wrapper.text()).toContain('0')
    const button = wrapper.find('button')
    await button.trigger('click')
    expect(wrapper.text()).toContain('1')
  })

})
```

We have the `Counter` component that updates the `count` reactive property when we click on the add button.

Then in our test, we check the rendered content with the `text` method.

And then we click the button and do the check again.

### Conclusion

We can simulate clicks and keyboard events in our tests and test the rendered content.