LoginSignup
28
11

More than 5 years have passed since last update.

JestでNuxt.js(Vue.js)のVuexをテスト

Last updated at Posted at 2018-12-07

みなさん、フロントエンドのテスト書いていますか?

Nuxt.js(Vue.js)でJestを使ってコンポーネントのテストについては情報がいろいろありましたが、VuexのStoreのテストについてあまり情報がなかったので、今回はVuexStoreのテストについてまとめました。

Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発」で作成したアプリケーションをJestでテストする手順についてまとめていきます。

テストの準備

テストに必要なツール

Jest

jest.png
https://github.com/facebook/jest

JestはFacebookが開発を進めるフロントエンドのテストランナです。
Facebook製なので当然Reactに対応していますが、その他JavaScriptアプリケーションのテストにも使用でき、Vue.jsでも利用できます。

RSpecライクな記法でテストコーディングが可能です。

Vue Test Utils

https://vue-test-utils.vuejs.org/ja/
Vue.jsアプリケーション用の公式単体テストライブラリです。
Vue-Router、VuexなどVue.jsのテストコーディングのために必要です。

Babel (@babel/core)

BabelはES2015以降のバージョンで記載されたJavaScriptをECMAScript5に変換するためのトランスコンパイラです。

babel-jest

JestをBabelに対応するためのツールです。

babel-preset-env

環境に従って必要なBabelプラグインを自動で決定するツールです。

babel-preset-vue-app

Vue開発のためのBabel設定を提供するツールです。

lodash.clonedeep

テスト実行のために直接必要になるわけではありませんが、VuexのテストでStoreオブジェクトをコピーするために利用します。

必要なツールを設定

必要なツールをインストールします。

> yarn add jest @vue/test-utils lodash.clonedeep babel-jest @babel/core @babel/preset-env babel-preset-vue-app lodash.clonedeep --dev

package.jsonにtestコマンド、Jest、Babelの設定を追加します。
targets->browsersオプションで対象ブラウザを指定しています。

オプションの詳細はこの辺りに記載があります。
https://babeljs.io/docs/en/babel-preset-env

/package.json
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "transform": {
      "^.+\\.js$": "babel-jest"
    }
  },
  "babel": {
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": {
            "browsers": [
              "last 2 versions"
            ]
          },
          "debug": true
        }
      ]
    ]
  },

この状態でテストを実行してみます。

> yarn run test
yarn run v1.10.1
$ jest
No tests found

まだテストコードがないので、エラーになりますが、テストが実行されています。

テストコーディング

Vuexのテスト

VuexのStoreのテストはこちらの書籍を参考にしました。

Nuxt.jsビギナーズガイド

GitHubにソースも公開されています。

/spec/store/messages.spec.js
require('dotenv').config()

const Vuex = require('vuex')
const messages = require('../../store/messages')
const { createLocalVue } = require('@vue/test-utils')
const cloneDeep = require('lodash.clonedeep')

const localVue = createLocalVue()
localVue.use(Vuex)

describe('store/message.js', () => {
  let store

  beforeEach(() => {
    store = new Vuex.Store(cloneDeep(messages))
  })

  describe('actions', () => {
    test('initMessagesでmessagesが初期化される', async () => {
      expect(store.getters['messages'].length).toBe(0)
      await store.dispatch('initMessages')
      expect(store.getters['messages'].length).not.toBe(0)
    })
  })
})

少し説明すると、require('dotenv').config()で、.envの値を読み込みます。

beforeEachで、cloneDeepを使ってmessagesのStoreをコピーし、オブジェクトを生成します。

  beforeEach(() => {
    store = new Vuex.Store(cloneDeep(messages))
  })

実際のテストはこちらです。
StoreのinitMessagesアクションをdispatchして、messagesステートにデータがセットされることを確認しています。

  describe('actions', () => {
    test('initMessagesでmessagesが初期化される', async () => {
      expect(store.getters['messages'].length).toBe(0)
      await store.dispatch('initMessages')
      expect(store.getters['messages'].length).not.toBe(0)
    })
  })

テストを実行します。

 PASS  spec/store/messages.spec.js
  store/message.js
    actions
      ✓ initMessagesでmessagesが初期化される (830ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.223s
Ran all test suites.

テストが成功しました!

まとめなど

テスト環境構築の際、Babelのエラーで苦しみました。。

this.setDynamic is not a function

とか、

Cannot find module '@babel/preset-env' 

とか。

Babelのバージョンに気をつけつつ、GitHubのissue情報や、Babel公式ドキュメントあたりにいろいろ情報ありますので、参考にしてください!

今回の記事では書かなかったですが、コンポーネント周りのテストをやろうとすると、やはりコンポーネントがテストしやすいIOの単位でまとまっていないと辛いです・・テストどう書けばいいの?ってなります。

やはり、TDDでテストを最初に書くことが大事ですね。

28
11
2

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
28
11