When testing Vue.js components, common test failures can arise due to various reasons. Here's how you could fix them:
- Await async operations - If your component is interacting with an API or performing asynchronous actions, make sure you await the completion of these operations before making assertions.
beforeEach(() => {
jest.useFakeTimers();
});
test('myComponent', async () => {
// Arrange
const wrapper = mount(MyComponent);
// Act
wrapper.vm.$refs.btn.click();
await flushPromises(); // wait for API call to complete
jest.advanceTimersByTime(1000); // or use fake timers if needed
// Assert
expect(myApiCall).toHaveBeenCalledWith('expectedData');
});
-
Use
v-model
- If your component relies on the model value, remember to include it in the template and check its state in tests.
<template>
<input v-model="myValue" />
</template>
<script>
export default {
data() {
return { myValue: '' };
}
};
</script>
In test file:
it('should update model value', () => {
const wrapper = mount(MyComponent);
wrapper.find('input').setValue('newData');
expect(wrapper.vm.myValue).toBe('newData');
});
-
Use
.trigger()
- When testing events, always use the.trigger()
method to dispatch the event on the component.
it('should emit an event', () => {
const wrapper = mount(MyComponent);
wrapper.find('.btn').trigger('click');
expect(wrapper.emitted().eventName).toBeTruthy();
});
-
Use
.setProps()
for prop changes - If you're testing how your component responds to prop changes, use the.setProps()
method instead of directly mutating the data property.
it('should react to prop change', async () => {
const wrapper = shallowMount(MyComponent);
// Arrange
wrapper.vm.$refs.btn.click(); // set initial state
await flushPromises(); // make sure update has occurred
// Act
wrapper.setProps({ propName: 'newValue' });
await wrapper.vm.$nextTick(); // wait for DOM to update
// Assert
expect(wrapper.find('.result').text()).toBe('expectedResult');
});
-
Use
mount()
instead ofshallowMount()
- If you're using a component with child components, consider testing it withmount()
, which includes the child components in the test. This can help identify and fix issues related to how parent and child components interact.
it('should render child component', () => {
const wrapper = mount(MyComponent);
// Assert
expect(wrapper.find('.child').exists()).toBeTruthy();
});
- Mock external dependencies - Use Jest's mocking capabilities to replace external dependencies that your component relies on, such as APIs or libraries. This helps isolate the component and ensures it works correctly in isolation.
jest.mock('api', () => ({
getData: jest.fn().mockResolvedValue('mockedData'),
}));
it('should handle API response', async () => {
const wrapper = mount(MyComponent);
// Act
wrapper.vm.$refs.btn.click();
await flushPromises();
// Assert
expect(api.getData).toHaveBeenCalledWith('expectedArgument');
});
Remember to cover all edge cases and ensure your tests are as comprehensive as possible, to catch potential bugs early on.