コンポーネントで vuelidate
検証の単体テストを作成しています。 $touch()
メソッドが非同期で呼び出されることがわかったので、$nextTick()
をexpect()
に使用する必要があります。 2つのnextTick()s
に対して2つの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()
}
})
})
_
このテストを2つの個別のテストに分割せずに実行するにはどうすればよいですか? $nextTick()
をネストすることはうまくいくと思いますが、より多くのテストには柔軟ではありません。
async
functions を使用できる場合は、await
the $nextTick
呼び出し。これにより、それらをネストする必要がなくなり、すべてを同じテストに保持できます。
そのようです:
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;
})
})
別のアプローチは、flushPromisesを使用することです。
_import flushPromises from 'flush-promises'
...
test('some asyn test', ascyn () => {
const wrapper = mount(MyComponent, { localVue })
wrapper.vm.$v.$touch()
await flushPromises()
})
_
flushPromises()
はpromise自体を返すので、.then().then()
などを使用して物事をチェーンする必要がある場合に役立ちます。