Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
My example component shows a counter (initially "0") and an "increase" button. It looks something like this:
<div ref="label">{{ counter }}</div>
ref="button"
@click="counter++"
Click me
If I test the click behaviour with Jest the following test will fail
it('increases the counter when the button is clicked', async () => {
const button = testComponent.findComponent({ ref: 'button' })
button.vm.$emit('click');
const label = testComponent.findComponent({ ref: 'label' })
expect(label.text()).toBe('1'); // fails
As I understand correctly, the event handler is called synchronously but the DOM update is still waiting in the async update queue of Vue. So to make the test work, I have to await Vue.$nextTick()
for the DOM to be updated:
it('increases the counter when the button is clicked', async () => {
const button = testComponent.findComponent({ ref: 'button' })
button.vm.$emit('click');
await Vue.$nextTick();
const label = testComponent.findComponent({ ref: 'label' })
expect(label.text()).toBe('1'); // succeeds
But I can await anything for the DOM to be updated. I can literally await an empty object and the test will succeed:
it('increases the counter when the button is clicked', async () => {
const button = testComponent.findComponent({ ref: 'button' })
button.vm.$emit('click');
await {};
const label = testComponent.findComponent({ ref: 'label' })
expect(label.text()).toBe('1'); // succeeds
I can't figure out why this is. Is it a specific behaviour of Jest? Why is this working?
–
await null
is a generic way to wait a bit until another promise that was created before settles, it works as intended only if another promise settles instantly:
Promise.resolve().then(() => console.log('foo'));
await null;
console.log('bar'); // output is foo bar
The documentation suggests to use flush-promises
that waits for a promise together with setTimeout
or setImmediate
and is a way to wait a bit more.
nextTick
returns a promise that instantly resolves, so await Vue.nextTick()
can be replaced with await null
. It's unlikely that this will be changed in future Vue versions but if it will, this will break the code that uses await null
. If a promise that can be awaited is accessible, like in case of nextTick
, it's semantically correct to chain it, at least this explicitly specifies what we wait for.
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.