# 発生したイベントのテスト
このページのテストのソースコードはこちらにあります。
アプリケーションが大きくなれば大きくなるほど、コンポーネントも増えていきます。親と子のコンポーネントでデータを共有するとき、子のコンポーネントがイベントを発火させて、親は反応します。
vue-test-utilsのwrapperAPIのemittedメソッドで発火したイベントを簡単に検証できます。ドキュメンテーションはこちらです。
# コンポーネントとテストを書く
簡単なコンポーネントを書きながら学びましょう。<Emitter>というコンポーネントを作って、このコードを書きます。
<template>
<div>
</div>
</template>
<script>
export default {
name: "Emitter",
methods: {
emitEvent() {
this.$emit("myEvent", "name", "password")
}
}
}
</script>
<style scoped>
</style>
そしてemitEventを呼び出すメソッドがあるテストを書きます。
import Emitter from "@/components/Emitter.vue"
import { shallowMount } from "@vue/test-utils"
describe("Emitter", () => {
it("2つの引数があるイベントを発火する", () => {
const wrapper = shallowMount(Emitter)
wrapper.vm.emitEvent()
console.log(wrapper.emitted())
})
})
vue-test-utilsのemitted APIでコンポーネントが発生したイベントが見えます。
yarn test:unitでテストを実行してみます。
PASS tests/unit/Emitter.spec.js
Emitter
✓ 2つの引数があるイベントを発火する (31ms)
console.log tests/unit/Emitter.spec.js:10
{ myEvent: [ [ 'name', 'password' ] ] }
# emittedのシンタックス
emittedはオブジェクトを返します。発生したイベントはプロパティになります。emitted().[event]で検証できます:
emitted().myEvent //=> [ [ 'name', 'password' ] ]
emitEventを二回呼び出してみます。
it("2つの引数があるイベントを発火する", () => {
const wrapper = shallowMount(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は配列を返します。最初に発生したイベントはemitted().emitEvent[0]でアクセスできます。イベントの引数をemitted().emitEvent[0][0]などでアクセスできます。
テストでイベントが発生したかを検証してみます。
it("2つの引数があるイベントを発火する", () => {
const wrapper = shallowMount(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でemitEventのthisにつけます。created、mountedのライフサイクルフックに重い処理をする場合、callで呼び出したらコンポーネントはマウントしないので、ライフサイクルメソッドも呼び出しません。thisを細かく指定したい時にも便利です。
# まとめ
vue-test-utilsのemittedAPIでコンポーネントによって発生したイベントを検証できます。emittedは関数です。呼び出したイベントはemittedが返すオブジェクトのプロパティになります。- そのプロパティは配列です。イベントが数回発生したら、
[0]、[1]などでアクセスできます。 - 発生したイベントの引数も配列になります。
[0]、[1]でアクセスします。 $emitをモックしてcallで呼び出して、レンダーせずに検証できます。
このページのテストのソースコードはこちらにあります。