How to test if a function is called when I submit a form with sinon?
Clash Royale CLAN TAG#URR8PPP
How to test if a function is called when I submit a form with sinon?
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'
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>
<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
1 Answer
1
The idea to test functions of vue components to have been called is to:
Create testing components with vue-test-utils
mount
or shallowMount
.
vue-test-utils
mount
shallowMount
Pass a methods
param in the options
to provide spies.
methods
options
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:
sinon
jest
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.
onSubmit
onSubmit
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.
<b-nav-form>
submit
onSubmit
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.
vue-test-utils
mount
shallowMount
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.
done
it()
click
let button = wrapper.find('button[type="submit"]')
button.trigger('click')
onSubmit
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This answer pretty much covers everything except
click
part. Instead of calling the method directly, you couldlet button = wrapper.find('button[type="submit"]')
and thenbutton.trigger('click')
This should call youronSubmit
method.– Cristi Jora
Aug 11 at 14:34