Это руководство было написано для Vue.js 3 и Vue Test Utils v2.
Версия для Vue.js 2 здесь.
# Тестирования пользовательских событий
С ростом приложения растёт количество компонентов. Когда им нужно общаться между собой, дочерний компонент может породить событие, а родитель ответить на него.
vue-test-utils
предоставляет emitted
API, который позволит нам сделать проверку на пользовательские события. Документацию для emitted
можно найти здесь.
Исходный код для тестов на этой странице можно взять тут.
# Написание компонента и теста к нему
Давайте сделаем простой компонент. Назовём его <Emitter>
и добавим следующий код:
<template>
<div>
</div>
</template>
<script>
export default {
name: "Emitter",
methods: {
emitEvent() {
this.$emit("myEvent", "name", "password")
}
}
}
</script>
Тест назовём emitEvent
:
import Emitter from "@/components/Emitter.vue"
import { mount } from "@vue/test-utils"
describe("Emitter.vue", () => {
it("Порождает событие с двумя аргументами", () => {
const wrapper = mount(Emitter)
wrapper.vm.emitEvent()
console.log(wrapper.emitted())
})
})
Используя emitted API, предоставленный нам vue-test-utils
, мы можем с лёгкостью посмотреть все порождённые события.
Запустим тест, написав yarn test:unit
.
PASS tests/unit/Emitter.spec.js
● Console
console.log tests/unit/Emitter.spec.js:10
{ myEvent: [ [ 'name', 'password' ] ] }
# Синтаксис emitted
emitted
возвращает объект. Порождённые события сохраняются, как свойства объекта. Вы можете проверять события, используя emitted().[event]
:
emitted().myEvent //=> [ [ 'name', 'password' ] ]
Давайте попробуем вызвать emitEvent
дважды:
it("Порождает событие с двумя аргументами", () => {
const wrapper = mount(Emitter)
wrapper.vm.emitEvent()
wrapper.vm.emitEvent()
console.log(wrapper.emitted().myEvent)
})
Запустим тест, написав yarn test:unit
.
console.log tests/unit/Emitter.spec.js:11
[ [ 'name', 'password' ], [ 'name', 'password' ] ]
emitted().emitEvent
возвращает массив. Первый экземпляр emitEvent
можно достать через emitted().emitEvent[0]
. Аргументы получают похожим синтаксисом: emitted().emitEvent[0][0]
и так далее.
Давайте сделаем реальную проверку для порождённых событий:
it("Порождает событие с двумя аргументами", () => {
const wrapper = mount(Emitter)
wrapper.vm.emitEvent()
expect(wrapper.emitted().myEvent[0]).toEqual(["name", "password"])
})
Тест проходит проверку.
# Тестирование событий без монтирования компонента
Иногда может потребоваться протестировать пользовательские события без монтирования компонента. Этого можно достичь, используя call
. Давайте напишем ещё один тест.
it("Порождает событие без монтирования компонента", () => {
const events = {}
const $emit = (event, ...args) => { events[event] = [...args] }
Emitter.methods.emitEvent.call({ $emit })
expect(events.myEvent).toEqual(["name", "password"])
})
Так как $emit
– обычный JavaScript объект, мы может замокать $emit
и использовать call
, чтобы прикрепить его к контексту this
из emitEvent
. Используя call
, вы также можете вызывать методы без монтирования компонента.
Использовать call
может быть полезно в ситуациях, где есть несколько тяжёлых функций в хуках жизненного цикла created
или mounted
, и вы не хотите их выполнять. Так как вы не монтируете компонент, функции из хуков никогда не выполнятся.
Также call
полезен при манипулировании контекстом this
.
Как правило, вы не хотите вызывать метод вручную, как мы это делаем здесь – если ваш компонент генерирует событие при нажатии кнопки, то вы, вероятнее всего, захотите выполнить wrapper.find ('button').сlick()
. Эта статья просто демонстрация других техник.
# Заключение
emitted
API изvue-test-utils
используется, чтобы проверять пользовательские событияemitted
- это метод возвращающий объект, в свойствах которого находятся порождённые события- каждое свойство из
emitted
является массивом. Чтобы достать экземпляр пользовательских событий, можно использовать синтаксис массивов[0]
,[1]
- аргументы для пользовательских событий также сохраняются в виде массивов, которые можно взять, используя
[0]
,[1]
. $emit
можно замокать, используяcall
. Проверки можно делать без монтирования компонента
Исходный код для тестов на этой странице можно взять тут.