Reputation: 1300
Let's assume a basic Bootstrap driven HTML form as part of a custom Vue component MyForm.vue
<template>
<form>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</template>
A unit test for testing if the template is rendered successfully is pretty simple
describe('MyForm', () => {
let wrapper;
beforeEach(...);
it('Should be rendered', () => {
let field = wrapper.find('#email');
expect(field.element.value).toEqual('');
});
});
This line works field.element.value
works because field.element
is of native type HtmlInputElement
with value
attribute.
What if I want access an attribute of a complex component let's say of b-form-input, the Bootstrap-Vue's default input element? b-form-input
is of type BFormInput
how to deal with it? Just cast the HtmlElement
to BFormInput
?
<template>
<b-form>
<b-form-group label="Email">
<b-form-input type="email" id="email"></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Submit</button>
</b-form>
</template>
How to test non-native components? Specially with type-safety means TypeScript. Any ideas?
Edit 03/01/2020
Following up to muka.gergely's answer I found this article. shallowMount
is stubbing all child components by default which prevents also event handling. Moreover shallowMount
allows to manually unstub components, in my case to unstub b-form
and b-button
for submit event testing.
const stubs = { // Originally intended to provide custom stubs, here used to unstub components
BButton,
BForm,
};
wrapper = shallowMount<MyComponent>(MyComponent, {stubs});
This effects that these components are rendered instead of stubbed. All remaining components like the b-form-input
are still automatically stubbed.
Upvotes: 4
Views: 1662
Reputation: 8329
You have to mount
the elements before testing them. You don't test the Vue component that you wrote, but the rendered output.
You should add vue-test-utils then your unit testing library (Jest and Mocha are well supported).
Here's a basic unit test for App.vue (with Vuetify and vue-router):
import Vue from 'vue'
import { shallowMount, createLocalVue } from '@vue/test-utils'
import Vuetify from 'vuetify'
import VueRouter from 'vue-router'
import App from '@/App';
Vue.use(Vuetify)
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter()
describe('App.vue', () => {
let vuetify
beforeEach(() => {
vuetify = new Vuetify()
})
it('mounts and renders', () => {
const wrapper = shallowMount(App, { localVue, vuetify, router });
expect(wrapper.html()).toBeTruthy();
});
});
You can see that I used shallowMount()
as I wasn't interested in testing the children of App.vue (they all have their separate unit tests). If I had been, then I should've used mount()
instead.
Upvotes: 2