vue.js - 测试 v-autocomplete 的观察者

vue.js - Test watchers of v-autocomplete

我有一个带有 v-autocomplete 的 vue.js SearchTest 组件。它有 selectsearch:

的观察者
// SearchTest.vue

<template>
  <v-autocomplete
    v-model="select"
    :items="items"
    :loading="isLoading"
    :search-input.sync="search"
    hide-no-data
    hide-selected
    placeholder="Type search query"
    return-object
  ></v-autocomplete>
</template>

<script>
export default {
  data: () => ({
    select: null,
    isLoading: false,
    search: null,
    items: [],
  }),
  watch: {
    select(val) {
      console.log('select: ', val);
    }
    search(val) {
      console.log('search: ', val);
    },
  },
};
</script>

<style></style>

我正在如下测试。我希望两个观察者都应该开火。事实上,只有 select 观察者开火了。 search 观察者没有。

// SearchTest.spec.js

import { createLocalVue, mount } from '@vue/test-utils'
import SearchTest from '@/components/SearchTest.vue'

import Vue from 'vue'
import Vuetify from 'vuetify'

Vue.use(Vuetify)

describe('SearchTest.vue', () => {
  const localVue = createLocalVue();
  const vuetify = new Vuetify({});
  let spy;
  beforeAll(() => {
    spy = jest.spyOn(console, 'log');
  })

  afterEach(() => {
    spy.mockClear();
  })

  it('Select', () => {
    const wrapper = mount(SearchTest, { localVue, vuetify });

    // Triggers select.
    wrapper.vm.select = 'select';
    wrapper.vm.$nextTick(() => {
      expect(spy).toBeCalled();  // OK
    });
  })

  it('Search', () => {
    const wrapper = mount(SearchTest, { localVue, vuetify });

    // Should trigger search, but fails.
    wrapper.vm.search = 'search';
    wrapper.vm.$nextTick(() => {
      expect(spy).toBeCalled();  // Fail
    });
  })
})

有通过 Search 测试的想法吗?

我不知道到底发生了什么,但我发现如果没有选择项目,v-autocomplete 内部会在创建时将搜索 属性 设置为 null (source).它通过使用 this.$nextTick 来实现,我想这会在测试中设置搜索值时引起问题。我找到了两种缓解这种情况的方法:

1

search 的更改和断言嵌套到另一个 $nextTick 中似乎是个窍门。

it('Search', () => {
  const wrapper = mount(SearchTest, { localVue, vuetify });

  wrapper.vm.$nextTick(() => {
    wrapper.vm.search = 'search';
    wrapper.vm.$nextTick(() => {
      expect(spy).toBeCalled();
    });
  });
})

2

对于此解决方案,我采用了 wrapper 的初始化并将其放入 beforeEach。它的作用基本相同,但我猜组件安装的时间不同,因此它不会与 v-autocomplete.

$nextTick 冲突
describe('SearchTest.vue', () => {
  const localVue = createLocalVue();
  const vuetify = new Vuetify({});
  let spy;
  let wrapper;

  beforeEach(() => {
    wrapper = mount(SearchTest, { localVue, vuetify });
  })

  beforeAll(() => {
    spy = jest.spyOn(console, 'log');
  })

  afterEach(() => {
    spy.mockClear();
  })

  it('Select', () => {
    // Triggers select.
    wrapper.vm.select = 'select';
    wrapper.vm.$nextTick(() => {
      expect(spy).toBeCalled();  // OK
    });
  })

  it('Search', () => {
    // Should trigger search, but fails.
    wrapper.vm.search = 'search';
    wrapper.vm.$nextTick(() => {
      expect(spy).toBeCalled();  // Fail
    });
  })
})