LoginSignup
0
0

More than 3 years have passed since last update.

Vuetify + Veevalidate 3 + Jest(test:unit) を動くところまでもってく

Last updated at Posted at 2020-08-12

Vuetify

本家のドキュメントのtestに関する章を参照
https://vuetifyjs.com/ja/getting-started/unit-testing/

Vuetifyの組み込み方は、specの最初に、次のように書く。

import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)

本家のドキュメントに次のような記述がありますが、この方法でlocalVueにvuetifyを読み込んでもうまくいきませんでした。

  //うまくいかなかった方法
  let vuetify

  beforeEach(() => {
    vuetify = new Vuetify()
  })

  it('should have a custom title and match snapshot', () => {
    const wrapper = mount(CustomCard, {
      localVue,
      vuetify,
      propsData: {
        title: 'Foobar',
      },
    })

Veevalidate

今回使用したのはVeevalidate 3.3.9 です。2系だと記述が違うので気を付けてください。

本家のドキュメントのtestに関する章を参照
https://logaretm.github.io/vee-validate/advanced/testing.html#asynchronous-testing

次のような記述例がありますが、$refを使った方法はうまく動作しませんでした(テンプレートもドキュメントと同じものにしてみたんですが…)

const error = wrapper.vm.$refs.provider.errors[0];

実際のinputやエラーを出力するDOMを見つけて値セットしたり、エラーメッセーを確認する方法は動作しました。以下の方法を参照してください。

値のセット方法

次のテンプレートの場合

<ValidationProvider name="email" v-slot="{ errors }" id="ID1" rules="required|email">
<v-text-field
  id="input_email"
  v-model="email"
  :error-messages="errors"
  label="E-mail"
  required
></v-text-field>
</ValidationProvider>

次のような方法で、値をセットして、エラーメッセージを確認できます

inputにIDを付けて直接見つける方法

wrapper.find('input_email').setValue('aaa');

ValiidationProviderにIDを付けて見つける方法

(エラー出力を得る方法と統一できるのでお勧め)

wrapper.find('#ID1').find('input').setValue('aaa');

バリデーション結果のチェック方法

const errorEl = wrapper.find('#ID1').find('.v-messages__message');
expect(errorEl.text()).toBe('Email must be valid');

Vuetifyが組み込まれているかの確認方法

どこまで動作してるのか全く掴めず、デバックに非常に苦労しました。
Vuetifyが取り込まれていないとレンダリングが実行されず、バリデーションの動作が成功するはずもありません。
動作確認として、次のコードを含んだテストを実行して、作成されたスナップショットファイルを確認する(スナップショットファイルが存在しない時は、結果をファイルに保存する動作になる。存在する時は、比較する動作)のがお勧めです

expect(wrapper.html()).toMatchSnapshot()

※余談
スナップショットを更新(正解データを更新する)時には、次のコマンドを実行

npm run test:unit -- --updateSnapshot

エラーと対処方

SyntaxError: Unexpected token 'export'

Veevalidateや、Vuetifyのモジュールの中で、SyntaxErrorが出ます。
これは、jestがTypescriptの記述を認識していないために発生しています。
paclage.jsonのtransformIgnorePatternsに"/node_modules"のtransformを行わない設定がある為に起きています。この行を削除するか、次の例のように、vurtifyとvee-validateディレクトリは除く記述にします。

  "jest": {
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/(?!(vuetify|vee-validate))"
    ],
    "preset": "@vue/cli-plugin-unit-jest"
  }

specファイル全体

import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)

import flushPromises from 'flush-promises';
import { mount, createLocalVue } from '@vue/test-utils'
const localVue = createLocalVue()

import AddEmail from '@/views/AddEmail.vue'

describe('AddEmail.vue', () => {
  // バリデーションエラーのテスト開始
  const mount_AddEmail = function() {
    return mount(AddEmail, {
      localVue,
      sync: false
    })
  }

  it('snapshot check', async () => {
    const wrapper = mount_AddEmail()
    expect(wrapper.html()).toMatchSnapshot()
  })
  it('dupcheck error if input "mike" in input of name', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID2').find('input').setValue('mike');    
    await flushPromises();
    const errorEl = wrapper.find('#ID2').find('.v-messages__message');
    expect(errorEl.text()).toBe('同じ名前は登録できません');
  })
  it('email address format check', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID1').find('input').setValue('aaa');    
    await flushPromises();
    const errorEl = wrapper.find('#ID1').find('.v-messages__message');
    expect(errorEl.text()).toBe('Email must be valid');
  })
  it('required condition of name', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID2').find('input').setValue('');    
    await flushPromises();
    const errorEl = wrapper.find('#ID2').find('.v-messages__message');
    expect(errorEl.text()).toBe('name can not be empty');
  })
  it('required condition of email', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID1').find('input').setValue('');    
    await flushPromises();
    const errorEl = wrapper.find('#ID1').find('.v-messages__message');
    expect(errorEl.text()).toBe('email can not be empty');
  })
})
0
0
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
0
0