我正在尝试使用 setTimeout 测试去抖动功能。这是一个带有 ajax api 调用的输入。我尝试了 jest.useFakeTimers() 和 jest.runAllTimers() 但没有成功。我还尝试运行 jest.advanceTimersByTime(501) - 因为我的超时时间为 500 毫秒,但仍然没有运气。
表单组件:
<template>
<div>
<div class="columns">
<div class="column">
<b-field :label="`${$t('categories')}`" label-for="categories">
<b-taginput
id="categories"
v-model="categories"
:data="filteredCategories"
:autocomplete="true"
:allow-new="false"
:open-on-focus="false"
icon="label"
@typing="getFiltered"
>
</b-taginput>
</b-field>
</div>
</div>
</div>
</template>
<script lang="ts">
import {
defineComponent,
reactive,
ref,
Ref,
toRefs
} from '@vue/composition-api'
import CategoriesRepository from '~/repository/categories'
export default defineComponent({
props: {
product: {
type: any,
default: () => {}
}
},
setup(props, context) {
const CategoriesAPI = new CategoriesRepository(context.root.$store)
const timeout: any = null
const state = reactive({
categories: [],
filteredCategories: [],
// needed to debounce search
searchTimeout: timeout
})
const getCategories = () => {
CategoriesAPI.all()
.then((response) => response.json())
.then((data) => {
state.categories = data
})
.catch(() => {
state.categories = []
})
}
const getFiltered = (search: string) => {
clearTimeout(state.searchTimeout)
// lines above are not reached by code coverage
state.searchTimeout = setTimeout(() => {
if (search.length > 0) {
CategoriesAPI.search(search)
.then((response) => response.json())
.then((data) => {
state.filteredCategories = data
})
.catch(() => {
state.filteredCategories = []
})
}
}, 500)
}
return {
...toRefs(state),
getFiltered
}
}
})
</script>
和 Form.spec.ts:
import { createLocalVue, mount } from '@vue/test-utils'
import CompositionApi from '@vue/composition-api'
import Buefy from 'buefy'
import mockFetch from '@/test'
import Form from '@/components/products/Form.vue'
const localVue = createLocalVue()
localVue.use(CompositionApi)
localVue.use(Buefy)
describe('Categories in product form', () => {
jest.useFakeTimers()
test('Test getting categories', async () => {
const wrapper = mount(Form, {
localVue
})
const fake_categories = ['test', 'food', 'travel']
// upload fetch
// it should be called only by getFiltered
window.fetch = mockFetch(200, fake_categories)
wrapper.find('#categories').setValue('test')
wrapper.find('#categories').trigger('change')
jest.runAllTimers()
// then I see in code coverage that state.searchTimeout = setTimeout(()... was not called.
})
和 mockFetch:
function mockFetch(status: number, data: any) {
return jest.fn().mockImplementation(() =>
Promise.resolve({
ok: true,
status: status,
json: () => data
})
)
}