I am using Vue v2.6 with Jest (v24.9) and Vue-Test-Utils (v1.03).
In order to mock a method I have seen two different syntaxes,
wrapper.vm.updateCart = jest.fn();
and
wrapper.setMethods({ updateCart: jest.fn() });
but the first is not documented, while the second is deprecated (see docs).
The problem is that with both these methods, the only way to make a test pass is to call the method with the parentheses inside the template, which is weird because all the docs I've read somehow encourage to use methods without parentheses in the templates.
So this test:
test('Click on .btn calls the right function', () => {
const wrapper = shallowMount(Modal, {
propsData: {
validate: jest.fn(),
},
});
wrapper.setMethods({ updateCart: jest.fn() });
const $btn = wrapper.find('.btn');
$btn.trigger('click');
expect(wrapper.vm.updateCart).toHaveBeenCalled();
});
will only pass if I call the method with parentheses:
<button class="btn" @click="updateCart()">
{{ dictionary('remove') }}
</button>
but will fail otherwise (eg. using @click="updateCart"
).
Which is the right syntax to test that an event in a template is calling a function?
And why the deprecation warning in the docs (here and here) define the setMethod
api as an anti-pattern?
Maybe it is just wrong to only test that an event in a template triggers a function because this behavior should already be guaranteed by the framework (Vue) and instead we should only focus on testing the function itself?
EDIT 07/02/2020
I have also tried a different syntax:
const spy = jest.spyOn(wrapper.vm, 'updateCart');
const $btn = wrapper.find('.btn');
$btn.trigger('click');
expect(spy).toHaveBeenCalled();
which prevents from overwriting the method and replaces the call to setMethods
, but still the test only passes when the function is called with parentheses.