LoginSignup
19
13

More than 3 years have passed since last update.

非同期な処理をしている create Vue コンポーネントのテスト

Last updated at Posted at 2019-05-10

前提条件

  • バージョン情報
    • Vue 2.6.10
    • Jest 24.5.0

TL;DR

DOMが絡むなら $nextTick , 絡まないなら setTimeout を使う。

実例

test.vue
<template>
  <div id="piyo">
    {{ hoge }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: '',
    };
  },
  async created() {
    this.hoge = await this.huga();
  },
  methods: {
    huga() {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve('it works');
        }, 100);
      });
    },
  },
};
</script>
test.spec.js
import { shallowMount } from '@vue/test-utils';
import Target from 'test.vue';

test('DOMをチェックする時', async () => {
  const wrapper = await shallowMount(Target);
  wrapper.vm.$nextTick(() => {
    const val = wrapper.find('#piyo');
    expect(val.text()).toEqual('it works');
  });
});

test('dataをチェックする時', (done) => {
  const wrapper = shallowMount(Target);
  setTimeout(() => {
    expect(wrapper.vm.hoge).toEqual('it works');
    done();
  }, 200);
});

問題点

1. $nextTick を使っている場合

mounted, Promise が resolve された時の2回チェックされることになり、テストには通るのですが Error in nextTick: "Error: expect(received).toEqual(expected) というエラー出てしまいます。。 参考文献にあるとおり、 FlushPromises を使えば解消するかもしれません(試してないです)。

2. setTimeout を使っている場合

待つ時間は長めに確保しないとうまく動かないことがあります。例えば、私の環境では待つ時間を 96ms にすると、1回目はうまく動き、2回目はコケます(キャッシュが効いて2回目のテストがちょっと早く動作し始めるためと思ってます)。こちらは、 huga() をモックしてしまえば解消できます。

test.spec.js
test('dataをチェックする時2', (done) => {
  const wrapper = shallowMount(Target, {
    methods: {
      huga: jest.fn().mockResolvedValue('it works'),
    },
  });
  setTimeout(() => {
    expect(wrapper.vm.hoge).toEqual('it works');
    done();
  }, 1); // 限りなく小さい値で良い
});

この場合、 huga() は Promise を返す関数なので、 huga() のテストも行ってあげるべきですが、Axios で API を叩いているだけな関数であればテストしなくてもよいかと(システム境界の外側なので)。Promise を返す関数であれば Jest でちゃんとテストできます

参考文献

19
13
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
19
13