LoginSignup
9
7

More than 5 years have passed since last update.

Vueコンポーネントが発生したイベントのテスト

Posted at

Vueコンポーネントが発生したイベントのテスト

アプリケーションが大きくなれば大きくなるほど、コンポーネントも増えていきます。親と子のコンポーネントをデータを共通するとき、子のコンポーネントがイベントを発火させて、親は反応します。

vue-test-utilswrapperAPIのemittedメソッドで発火したイベントを簡単に検証できます。ドキュメンテーションはこちらです。


これは最近作り始めたVueテストハンドブックからの記事です。貢献したい方はどうぞ。

このページのテストのソースコードはこちらにあります。


コンポーネントとテストを書く

簡単なコンポーネントを書きながら学びましょう。<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-utilsemitted 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をモックして、callemitEventthisにつけます。createdmountedのライフサイクルフックに重い処理をする場合、callで呼び出したらコンポーネントはマウントしないので、ライフサイクルメソッドも呼び出しません。thisを細かく指定したい時にも便利です。

まとめ

  • vue-test-utilsemittedAPIでコンポーネントによって発生したイベントを検証できます。
  • emittedは関数です。呼び出したイベントはemittedが返すオブジェクトのプロパティになります。
  • そのプロパティは配列です。イベントが数回発生したら、[0][1]などでアクセスできます。
  • 発生したイベントの引数も配列になります。[0][1]でアクセスします。
  • $emitをモックしてcallで呼び出して、レンダーせずに検証できます。

このページのテストのソースコードはこちらにあります。

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7