3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

翻訳 Vuex の mutation のテスト

Posted at

Mutation をテストする

Mutation のテストだけを独立しておこなう場合には、複雑な手順は全く必要ありません。Mutation は通常の JavasScript の関数の範囲で書かれているからです。このページでは Mutation だけの独立したテストについて取り上げます。コンポーネントが Mutation に commit する際の Mutation のテストをしたい場合には、こちらをご覧ください。

Testing mutations in isolation is very straight forward, because mutations are just regular JavaScript functions. This page discusses testing mutations in isolation. If you want to test mutations in the context of a component committing a mutation, see here.

このページで実装していくテストの完成形のコードはこのリポジトリにも配置してあります。

The test used in the following example can be found here.

Mutation を作成する

Mutation は基本的には次のような定型パターンをとります。つまり、情報を受け取って、その情報に対していくつかの処理をして、そしてその加工された情報を state に割り当てます。次のコードは ADD_POST mutation の大枠です。まだ大枠しか書かれていませんが、この Mutation の実装が完成した際には、Mutation は payload として送られてきた post オブジェクトをとして受け取り、post.idstate.postIds に追加します。同時に post オブジェクトを state.posts オブジェクトに対して、key が post.id となるプロパティとして追加します。これは Vuex を用いたアプリケーションにおいてよく取られる手法です。

Mutations tend to following a set pattern. Get some data, maybe do some processing, then assign the data to the state. Here is the outline of an ADD_POST mutation. Once implemented, it will receive a post object in the payload, and add the post.id to state.postIds. It will also add the post object to the state.posts object, where the key is the post.id. This is a common pattern in apps using Vuex.

ではこの mutation を TDD の手法に則って開発していきましょう。まずは mutation を以下のように書いて始めましょう。

We will develop it using TDD. The start of the mutation is as follows:

export default {
  SET_USER(state, { post }) {

  }
}

次にテストを書くことにしましょう。テストのエラーメッセージを参考にしながら開発を進めます。

Let's write the test, and let the error messages guide our development:

import mutations from "@/store/mutations.js"

describe("SET_POST", () => {
  it("adds a post to the state", () => {
    const post = { id: 1, title: "Post" }
    const state = {
      postIds: [],
      posts: {}
    }

    mutations.SET_POST(state, { post })

    expect(state).toEqual({
      postIds: [1],
      posts: { "1": post }
    })
  })
})

yarn test:unit を実行してテストを走らせます。すると、次のようなテスト失敗に関するメッセージが表示されます。

Running this test with yarn test:unit yields the following failure message:

FAIL  tests/unit/mutations.spec.js
● SET_POST › adds a post to the state

  expect(received).toEqual(expected)

  Expected value to equal:
    {"postIds": [1], "posts": {"1": {"id": 1, "title": "Post"}}}
  Received:
    {"postIds": [], "posts": {}}

ではメッセージを参考に、 post.idstate.postIds に追加することにしましょう。

Let's start by adding the post.id to state.postIds:

export default {
  SET_POST(state, { post }) {
    state.postIds.push(post.id)
  }
}

変更したら再度 yarn test:unit を実行すると、次のようなメッセージが表示されはずです。

Now yarn test:unit yields:

Expected value to equal:
  {"postIds": [1], "posts": {"1": {"id": 1, "title": "Post"}}}
Received:
  {"postIds": [1], "posts": {}}

postIds は良いみたいですね。しかし state.posts 関しては post が本来追加されていないといけませんね。このように期待しない挙動になってしまっているのは、Vue のリアクティビティシステムが、単に post[post.id] = post と書くだけでは機能しないからです。より詳しくはこちらをご覧ください。これに対応するためには、新しいオブジェクトを Object.assign もしくは ... オペレーターを使って生成すれば良いでしょう。このガイドでは ... を使って post を state.posts にアサインしていきます。

postIds looks good. Now we just need to add the post to state.posts. Because of how the Vue reactivity system works we cannot simply write post[post.id] = post to add the post. More details can be found here. Basically, you need to create a new object using Object.assign or the ... operator. We will use the ... operator to assign the post to state.posts:

export default {
  SET_POST(state, { post }) {
    state.postIds.push(post.id)
    state.posts = { ...state.posts, [post.id]: post }
  }
}

さあ、これでテストが通りましたね!

Now the test passes!

結論

Vuex の mutation に対するテストには、Vue もしくは Vuex 特有の要素は一切ありません。なぜなら mutation は JavaScript の普通の関数だからです。単に mutation を import して、必要なテストをすればいいだけです。唯一注意しなければいけないことがあるとすれば、Vue のリアクティビティに関するクセです。このクセが Vuex にも影響しています。Vue のリアクティビティシステムに関してより詳しく知りたい場合にはこちらを読んでください。

Testing Vuex mutations requires nothing specific to Vue or Vuex, since they are just regular JavaScript functions. Simply import them and test as needed. The only thing to be careful of is Vue's reactivity caveats, which apply to Vuex as well. You can read more about the reactivity system and common caveats here.

このページが扱ってきた内容をまとめると次のようになります。

The page discussed:

  • Vuex の mutation は通常の JavaScript の関数である

  • Mutation はメインの Vue アプリケーションとは切り離した状態でテストすることができ、またそうしたほうがよい

  • Vuex mutations are regular JavaScript functions

  • Mutations can, and should, be tested in isolation from the main Vue app

このページで作成したテストはここでみることができます。

The test used in the above example can be found here.

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?