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

Posted

技术标签:

【中文标题】vue.js - 测试 v-autocomplete 的观察者【英文标题】:vue.js - Test watchers of v-autocomplete 【发布时间】:2021-06-24 13:28:34 【问题描述】:

我有一个带有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 测试有什么想法吗?

【问题讨论】:

【参考方案1】:

我不知道到底发生了什么,但我发现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
    );
  )
)

【讨论】:

谢谢!这对我有用。第二种解决方案优雅简洁。

以上是关于vue.js - 测试 v-autocomplete 的观察者的主要内容,如果未能解决你的问题,请参考以下文章

无法从自定义自动完成搜索栏中选择项目 (Vue.js/Vuetify.js)

Vuetify v-autocomplete 和 v-data-table 不起作用

是否可以更改 v-autocomplete 宽度?

将自定义部分添加到 v-autocomplete 下拉列表

v-autocomplete 并将用户输入设置为其值

更改样式 active v-autocomplete