14

I'm writing unit tests for vuelidate validation in my component. I figured out that the $touch() method is called asynchronously, so I need to use $nextTick() for the expect(). The problem appears when I need two nextTick()s for two expect()s.

describe('Validations', () => { let data let myComponent beforeEach(() => { data = () => { propertyABC = 'not allowed value' } myComponent = localVue.component('dummy', {template: '<div></div>', validations, data}) it('Properly validates propertyABC', (done) => { Vue.config.errorHandler = done let wrapper = mount(myComponent, {localVue}) wrapper.vm.$v.$touch() wrapper.vm.$nextTick(() => { expect(wrapper.vm.$v.propertyABC.$error).to.be.true # fails, because propertyABC === 'allowed value', adn thus $error is false done() } wrapper.vm.propertyABC = 'allowed value' wrapper.vm.$v.propertyABC.$touch() wrapper.vm.$nextTick(() => { expect(wrapper.vm.$v.proprtyABC.$error).to.be.false done() } }) }) 

How can I run this test without splitting it into two separate tests? I think nesting the $nextTick() might work, but it would be not flexible for higher amount of tests.

1
  • Promise.all? Commented Feb 12, 2018 at 17:15

2 Answers 2

24

If you're able to use async functions, then you could await the $nextTick calls. This would avoid having to nest them and would keep everything in the same test.

Like so:

describe('Validations', () => { let data; let myComponent; beforeEach(() => { data = () => ({ propertyABC = 'not allowed value' }); myComponent = localVue.component('dummy', {template: '<div></div>', validations, data}); }); it('Properly validates propertyABC', async () => { let wrapper = mount(myComponent, {localVue}); wrapper.vm.$v.$touch(); await wrapper.vm.$nextTick(); expect(wrapper.vm.$v.propertyABC.$error).to.be.true; wrapper.vm.propertyABC = 'allowed value'; wrapper.vm.$v.propertyABC.$touch(); await wrapper.vm.$nextTick(); expect(wrapper.vm.$v.proprtyABC.$error).to.be.false; }) }) 
Sign up to request clarification or add additional context in comments.

Comments

5

Another approach is to use flushPromises.

import flushPromises from 'flush-promises'; ... test('some async test', async () => { const wrapper = mount(MyComponent, { localVue }); wrapper.vm.$v.$touch(); await flushPromises(); }); 

flushPromises() returns a promise itself, so its useful when you need/want to chain things using .then().then() etc...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.