lodash
lodash copied to clipboard
How to test a Vue debounced method?
I have a Vue application that uses the debounce function in a search input. I want to test my search input component but it's not being fired. I've tried to test using Jest fake timers but it didn't work, debounce is never fired (then my method is never fired too).
My code is shown below:
<template>
<input type="text" @input="onSearchInput" />
</template>
<script>
import { debounce } from 'lodash';
export default {
name: 'CommonFilter',
emits: ['change'],
methods: {
onSearchInput: debounce(function(e) {
// do something
this.$emit('change', {search: e.target.value});
}, 700),
}
};
</script>
I tried to test using the following code.
it('emits @change event when type', async () => {
jest.useFakeTimers();
const wrapper = mount(CommonFilter);
const $input = wrapper.find('.search-input');
await $input.setValue('jackfruit');
jest.runOnlyPendingTimers();
expect(wrapper.emitted().change).toBeTruthy();
});
Thank you for any help.
@geeksilva97
<script>
export default {
name: "Header",
data() {
return {
searchText: "github",
};
},
methods: {
// If the user types very fast, will allow the execution of func only when the user has stopped typing in the search bar
DebounceFn: function () {
if (this.searchText.length >= 3) {
// schedule the execution after user stopped typing in the search bar
setTimeout(() => {
this.$emit("onSearch", this.searchText);
}, 1000);
}
},
},
};
</script>
it("emits an event with search text", async () => {
jest.useFakeTimers();
const wrapper = mount(Header);
// calling emitEvent twice
wrapper.vm.DebounceFn();
wrapper.vm.DebounceFn();
jest.runOnlyPendingTimers();
// you can console it and check
console.log(wrapper.emitted().onSearch[0]);
expect(wrapper.emitted().onSearch[0]).toEqual(["github"]);
});

@geeksilva97 How did you solve this? The above answer only applies to setTimeout not _.debounce
According to this comment https://github.com/facebook/jest/issues/3465#issuecomment-351186130 you can workaround this issue by mocking debounce with jest.mock('lodash/debounce', () => jest.fn(fn => fn)); in your setupJest.js.
@geeksilva97 How did you solve this? The above answer only applies to setTimeout not _.debounce
I couldn't. All the answers here are about mock. Looks like a kind of integration test with the real debounce doesn't work.
According to this comment jestjs/jest#3465 (comment) you can workaround this issue by mocking
debouncewithjest.mock('lodash/debounce', () => jest.fn(fn => fn));in yoursetupJest.js.
this worked for me, thanks
@geeksilva97 How did you solve this? The above answer only applies to setTimeout not _.debounce
I couldn't. All the answers here are about mock. Looks like a kind of integration test with the REAL debounce doesn't work.
@geeksilva97 How did you solve this? The above answer only applies to setTimeout not _.debounce
I couldn't. All the answers here are about mock. Looks like a kind of integration test with the REAL debounce doesn't work.
(just realized I had commented with the wrong account)