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.id
を state.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.id
を state.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.