# 発生したイベントのテスト
このページのテストのソースコードはこちらにあります。
アプリケーションが大きくなれば大きくなるほど、コンポーネントも増えていきます。親と子のコンポーネントでデータを共有するとき、子のコンポーネントがイベントを発火させて、親は反応します。
vue-test-utils
のwrapper
APIの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
のemitted
APIでコンポーネントによって発生したイベントを検証できます。emitted
は関数です。呼び出したイベントはemitted
が返すオブジェクトのプロパティになります。- そのプロパティは配列です。イベントが数回発生したら、
[0]
、[1]
などでアクセスできます。 - 発生したイベントの引数も配列になります。
[0]
、[1]
でアクセスします。 $emit
をモックしてcall
で呼び出して、レンダーせずに検証できます。
このページのテストのソースコードはこちらにあります。