I have a problem understand testing Vue components. In the component testing docs, it says:
Component tests should focus on the component's public interfaces rather than internal implementation details. For most components, the public interface is limited to: events emitted, props, and slots. When testing, remember to test what a component does, not how it does it.
Say you have a Form Component:
<template>
<form @submit.prevent="submitForm">
Email: <input type="text" data-test="email" v-model="user.email" /> <br />
First: <input type="text" data-test="first" v-model="user.first" /> <br />
Last: <input type="text" data-test="last" v-model="user.last" /> <br />
<button type="submit">Create User</button>
</form>
</template>
<script>
import { createUser } from '@/api'
import { notify } from '@/helpers'
export default {
data: () => ({
user: {
email: '',
first: '',
last: ''
}
}),
methods: {
async submitForm() {
try {
const result = await createUser(this.user)
notify.success({
message: 'Success'
})
this.$router.push({ name: 'Home' })
} catch {
notify.error({
message: 'Error occurred'
})
}
}
}
}
</script>
and here's how I test it:
import router from '@/router';
import * as fetchers from '@/api'
import { notify } from '@/helpers'
import fp from 'flush-promises'
test('should save car details', async () => {
const successSpy = jest.spyOn(notify, 'success')
const createUserSpy = jest.spyOn(fetchers, 'createUser')
const routerPushSpy = jest.spyOn(router, 'push')
const wrapper = mount(Form)
await wrapper.find('[data-test="email"]').setValue('test@email.com');
await wrapper.find('[data-test="first"]').setValue('John');
await wrapper.find('[data-test="last"]').setValue('Doe');
await wrapper.find('button').trigger('click')
await fp();
expect(successSpy).toHaveBeenCalledWith({
message: 'Success',
})
expect(createUserSpy).toHaveBeenCalledWith({
email: 'test@email.com',
first: 'John',
last: 'Doe'
});
expect(routerPushSpy).toHaveBeenCalledWith({ name: 'Home' });
});
While this test works, I am not sure if this is the correct way of component testing based on Vue docs. Looks like I'm testing internal details in that test?
How should I do it?