How to test if a function is called when I submit a form with sinon?

The name of the pictureThe name of the pictureThe name of the pictureClash 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()





This answer pretty much covers everything except click part. Instead of calling the method directly, you could let button = wrapper.find('button[type="submit"]') and then button.trigger('click') This should call your onSubmit method.
– Cristi Jora
Aug 11 at 14:34



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.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS