Jest 'toHaveBeenCalled' for click events only works after two clicks? (Testing a Vue app)
A simple component:
<template>
<div>
<p>
count
</p>
<button @click="increment" data-test="increment">Increment</button>
</div>
</template>
<script>
export default
data ()
return
count: 0
,
methods:
increment ()
this.count++
</script>
And my test:
import TestExperiment from '@/components/TestExperiment'
import createLocalVue, shallowMount from '@vue/test-utils'
const localVue = createLocalVue()
describe('testexperiment.test.js', () =>
const cmp = shallowMount(TestExperiment,
localVue
)
const increment = jest.spyOn(cmp.vm, 'increment')
const incrementButton= cmp.find('[data-test="increment"]')
test('clicking increment button calls increent', () =>
expect(incrementButton.exists()).toBe(true)
incrementButton.trigger('click')
// Checking call here fails:
// expect(increment).toHaveBeenCalled()
// Function was still obviously called
expect(cmp.vm.count).toBe(1)
incrementButton.trigger('click')
// Checking call here passes:
expect(increment).toHaveBeenCalled()
)
)
As you can see, I trigger a click on incrementButton twice.
After the first call, if I test if the method 'increment' was called, it returns false. However, count is indeed incremented. After the second call, it registers that it was in fact called (if I test how many times it was called, it asserts that it was called one time, even if count is 2, clearly having been incremented twice).
What am I missing about how Jest/Vue works?
vue.js jestjs vue-test-utils
add a comment |
A simple component:
<template>
<div>
<p>
count
</p>
<button @click="increment" data-test="increment">Increment</button>
</div>
</template>
<script>
export default
data ()
return
count: 0
,
methods:
increment ()
this.count++
</script>
And my test:
import TestExperiment from '@/components/TestExperiment'
import createLocalVue, shallowMount from '@vue/test-utils'
const localVue = createLocalVue()
describe('testexperiment.test.js', () =>
const cmp = shallowMount(TestExperiment,
localVue
)
const increment = jest.spyOn(cmp.vm, 'increment')
const incrementButton= cmp.find('[data-test="increment"]')
test('clicking increment button calls increent', () =>
expect(incrementButton.exists()).toBe(true)
incrementButton.trigger('click')
// Checking call here fails:
// expect(increment).toHaveBeenCalled()
// Function was still obviously called
expect(cmp.vm.count).toBe(1)
incrementButton.trigger('click')
// Checking call here passes:
expect(increment).toHaveBeenCalled()
)
)
As you can see, I trigger a click on incrementButton twice.
After the first call, if I test if the method 'increment' was called, it returns false. However, count is indeed incremented. After the second call, it registers that it was in fact called (if I test how many times it was called, it asserts that it was called one time, even if count is 2, clearly having been incremented twice).
What am I missing about how Jest/Vue works?
vue.js jestjs vue-test-utils
add a comment |
A simple component:
<template>
<div>
<p>
count
</p>
<button @click="increment" data-test="increment">Increment</button>
</div>
</template>
<script>
export default
data ()
return
count: 0
,
methods:
increment ()
this.count++
</script>
And my test:
import TestExperiment from '@/components/TestExperiment'
import createLocalVue, shallowMount from '@vue/test-utils'
const localVue = createLocalVue()
describe('testexperiment.test.js', () =>
const cmp = shallowMount(TestExperiment,
localVue
)
const increment = jest.spyOn(cmp.vm, 'increment')
const incrementButton= cmp.find('[data-test="increment"]')
test('clicking increment button calls increent', () =>
expect(incrementButton.exists()).toBe(true)
incrementButton.trigger('click')
// Checking call here fails:
// expect(increment).toHaveBeenCalled()
// Function was still obviously called
expect(cmp.vm.count).toBe(1)
incrementButton.trigger('click')
// Checking call here passes:
expect(increment).toHaveBeenCalled()
)
)
As you can see, I trigger a click on incrementButton twice.
After the first call, if I test if the method 'increment' was called, it returns false. However, count is indeed incremented. After the second call, it registers that it was in fact called (if I test how many times it was called, it asserts that it was called one time, even if count is 2, clearly having been incremented twice).
What am I missing about how Jest/Vue works?
vue.js jestjs vue-test-utils
A simple component:
<template>
<div>
<p>
count
</p>
<button @click="increment" data-test="increment">Increment</button>
</div>
</template>
<script>
export default
data ()
return
count: 0
,
methods:
increment ()
this.count++
</script>
And my test:
import TestExperiment from '@/components/TestExperiment'
import createLocalVue, shallowMount from '@vue/test-utils'
const localVue = createLocalVue()
describe('testexperiment.test.js', () =>
const cmp = shallowMount(TestExperiment,
localVue
)
const increment = jest.spyOn(cmp.vm, 'increment')
const incrementButton= cmp.find('[data-test="increment"]')
test('clicking increment button calls increent', () =>
expect(incrementButton.exists()).toBe(true)
incrementButton.trigger('click')
// Checking call here fails:
// expect(increment).toHaveBeenCalled()
// Function was still obviously called
expect(cmp.vm.count).toBe(1)
incrementButton.trigger('click')
// Checking call here passes:
expect(increment).toHaveBeenCalled()
)
)
As you can see, I trigger a click on incrementButton twice.
After the first call, if I test if the method 'increment' was called, it returns false. However, count is indeed incremented. After the second call, it registers that it was in fact called (if I test how many times it was called, it asserts that it was called one time, even if count is 2, clearly having been incremented twice).
What am I missing about how Jest/Vue works?
vue.js jestjs vue-test-utils
vue.js jestjs vue-test-utils
edited Nov 15 '18 at 20:33
skyboyer
4,18811333
4,18811333
asked Nov 15 '18 at 19:25
Benjamin FriedmanBenjamin Friedman
12
12
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You need to use the Vue Test Utils setMethod
method:
const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()
wrapper.setMethods( clickMethod: clickMethodStub )
wrapper.find('button').trigger('click')
expect(clickMethodStub.called).toBe(true)
The reason it does not work in your example is because the element that you dispatch a click on has the original handler that the component created when it was instantiated.
It works after two calls to trigger
because the initial call causes a re render, and the patched element has its handler updated to use the stub method that you added to the instance.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53326620%2fjest-tohavebeencalled-for-click-events-only-works-after-two-clicks-testing-a%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You need to use the Vue Test Utils setMethod
method:
const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()
wrapper.setMethods( clickMethod: clickMethodStub )
wrapper.find('button').trigger('click')
expect(clickMethodStub.called).toBe(true)
The reason it does not work in your example is because the element that you dispatch a click on has the original handler that the component created when it was instantiated.
It works after two calls to trigger
because the initial call causes a re render, and the patched element has its handler updated to use the stub method that you added to the instance.
add a comment |
You need to use the Vue Test Utils setMethod
method:
const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()
wrapper.setMethods( clickMethod: clickMethodStub )
wrapper.find('button').trigger('click')
expect(clickMethodStub.called).toBe(true)
The reason it does not work in your example is because the element that you dispatch a click on has the original handler that the component created when it was instantiated.
It works after two calls to trigger
because the initial call causes a re render, and the patched element has its handler updated to use the stub method that you added to the instance.
add a comment |
You need to use the Vue Test Utils setMethod
method:
const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()
wrapper.setMethods( clickMethod: clickMethodStub )
wrapper.find('button').trigger('click')
expect(clickMethodStub.called).toBe(true)
The reason it does not work in your example is because the element that you dispatch a click on has the original handler that the component created when it was instantiated.
It works after two calls to trigger
because the initial call causes a re render, and the patched element has its handler updated to use the stub method that you added to the instance.
You need to use the Vue Test Utils setMethod
method:
const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()
wrapper.setMethods( clickMethod: clickMethodStub )
wrapper.find('button').trigger('click')
expect(clickMethodStub.called).toBe(true)
The reason it does not work in your example is because the element that you dispatch a click on has the original handler that the component created when it was instantiated.
It works after two calls to trigger
because the initial call causes a re render, and the patched element has its handler updated to use the stub method that you added to the instance.
answered Nov 23 '18 at 17:32
EddEdd
2,42711532
2,42711532
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53326620%2fjest-tohavebeencalled-for-click-events-only-works-after-two-clicks-testing-a%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown