使用jest測試vue組件中設置了debounce的函數
代碼中用到了lodash.debounce來避免一些高頻操作導致的函數在短時間內被反覆執行,需要測試函數中包含的接口及參數。待測試代碼如下:
// MyVueComponent.vue
import _ from 'lodash'
getPrice: _.debounce(function() {
myApi
.calculateApi({
params: {
key1: value1
},
data: {
params: {
key2: value2
}
}
})
.then(response => {
this.price = response.data.priceKey
})
}, 300)
需要測試下調用this.getPrice()函數的時候,myApi.calculateApi接口被正確調用。
踩了好多坑之後,有2種方法可測試成功。
1.藉助mockdate插件,mock當前時間。
通過修改當前時間,達到定時設置時間,從而調用對應函數。
// MyVueComponent.spec.js
function getComponent(options = {}) {
return shallowMount(
MyVueComponent,
extend(
true,
{
propsData: {
props1: value1
},
store
},
options
)
)
}
let fakePriceApi
beforeAll(() => {
fakeApi = jest.spyOn(myApi, 'calculateApi').mockResolvedValue({data: {result: {}}})
})
// MockDate is used to be change when now is.
import MockDate from 'mockdate'
function fastforward(time) {
let now = Date.now() + time
MockDate.set(now)
jest.runTimersToTime(time)
}
describe('獲取價格接口正確調用', () => {
beforeEach(() => {
jest.useFakeTimers()
})
afterEach(() => {
jest.clearAllTimers()
})
it('影響價格的因素短時間內變化多次時,接口只會調用一次', () => {
let wrapper = getComponent()
wrapper.vm.getPrice()
wrapper.vm.getPrice()
wrapper.vm.getPrice()
fastforward(50) // 第 50 ms時,接口未被調用
expect(fakeApi).not.toHaveBeenCalled()
fastforward(200) // 第 250 ms 時,接口被調用
expect(fakeApi).toHaveBeenCalledTimes(1)
})
it('查詢價格接口調用正確', () => {
let wrapper = getComponent({
propsData: {
xxxx: 'aaaaa'
}
})
wrapper.vm.getPrice()
fastforward(250) // 第 250 ms
expect(fakeApi).toHaveBeenCalledWith(
expect.objectContaining({
params: {
key1: value1
},
data: {
params: expect.objectContaining({
key2: value2
})
}
})
)
})
})
2. 將debounce mock爲立即執行的函數
不去驗證getPrice是否會被debounce,因爲debounce是第三方模塊的方法,我們默認認爲是正確的,我們要驗證的是getPrice能夠正確觸發方法, 函數內部的接口能被正確調用即可。
// 通過mock將lodash的debounce修改爲立即執行的函數
jest.mock('lodash/debounce', () => jest.fn(fn => fn))
只需添加一行mock代碼,即可測試通過。
踩坑記錄
- 方法1不使用mockdate,而是使用jest.runOnlyPendingTimers()。測試時,接口不能被成功調用。在查了許多資料後,這可能是lodash的debounce機制與jest的timer-mocks 無法兼容。
參考文獻:
- https://blog.csdn.net/duola8789/article/details/80434962
- https://www.jianshu.com/p/c5d45306d374
- https://blog.csdn.net/TMQ1225/article/details/81133855