intro:
I want to test that if I click on the submit button, the onSubmit function is called. I assume this is possible from what I understand when I read the documentation:
expected output:
actual output:
context:
in my test:
import NavBar from '@/components/layout/NavBar.vue'
in that component I have a (simplified version here) form:
<b-nav-form @submit="onSubmit">
<b-form-input />
<b-button type="submit">Search</b-button>
</b-nav-form>
I want to test that if I click on the submit button, the onSubmit function is called.
My setup is Vue, BootstrapVue and Sinon. I understand I have to setup a spy that listens to a function being called.
This is the actual script in my component if that is helpful:
<script>
export default {
data () {
return {
query: ''
}
},
methods: {
onSubmit () {...}
}
}
</script>
example that I understand:
it('a true example', () => {
var f = {
onSubmit: function(query) {
this.query = query;
}
}
var onSubmitSpy = sinon.spy(f, 'onSubmit');
f.onSubmit('Club')
console.log(onSubmitSpy.callCount); // is 1
onSubmitSpy.restore();
})
But this is not connected to for example clicking on the button in the form.
Please advise
The idea to test functions of vue components to have been called is to:
Create testing components with vue-test-utils
mount
or shallowMount
.
Pass a methods
param in the options
to provide spies.
Perform actions in the component that calls the spied method, then assert the method was really called.
I don't have sinon
experience, am only used to test vue components with jest
, but the thing should be something like the following:
import NavBar from '@/components/layout/NavBar.vue'
import {shallowMount} from 'vue-test-utils';
it('asserting onSubmit calls', () => {
// given
var onSubmit = sinon.spy();
var wrapper = shallowMount(NavBar, {
methods: {
onSubmit();
}
});
var vm = wrapper.vm;
// when
vm.onSubmit();
// then (I dont really dont know if this is valid sinon syntax)
assertTrue(onSubmit.called);
// or, with jest syntax:
// expect(onSubmit).toHaveBeenCalled();
})
Now, the code snippet should work, but there are problems with this test: we are asserting that when we call the component onSubmit
, the onSubmit
spy gets called. This is not the great thing.
Your test would probably need to assert somehing like: when the <b-nav-form>
component emits a submit
event, then the onSubmit
spy gets called.
That would be a more complex test, for two reasons:
Because a child component is involved. To really render child components in a vue-test-utils
test, you need to use mount
instead of shallowMount
. This is difficult as you need to provided childs props and dependencies, so get used to the shallowMount and mount differences.
When you start testing events, chances are some synchrony is involved, so you need to wait for the event to propagate and get your component method called. This usually involves to pass done
callback to it()
blocks.