0

I have next test (simplified):

import { expect } from "chai";
import { mount } from "@vue/test-utils";

const Component = {
  template: "<p>{{ innerValue }}</p>",
  props: {
    value: String
  },
  data() {
    return {
      delayedValue: null,
      innerValue: null
    };
  },
  watch: {
    value: {
      immediate: true,
      async handler(val) {
        console.log(val);
        this.delayedValue = val;
        let text = "";
        if (val) {
          text = await Promise.resolve(val);
        }

        if (this.delayedValue == val) {
          this.innerValue = text;
        }
      }
    }
  }
};

it.only("should update inner value", async () => {
  const wrapper = mount(Component);
  await wait(100);
  wrapper.setProps({ value: "good" });
  await wait(100);
  expect(wrapper.vm.innerValue).be.equal("good");
});

function wait(time) {
  return new Promise(resolve => {
    setTimeout(resolve, time);
  });
}

when test is executed console output shows:

undefined
good
undefined

Meaning handler was called 3 time. First undefined corresponds to initial state of the component and is called because immediate:true. Second 'good' is due to setProps call, but the issue is in a third call with undefined that is happened before Promise is resolved. That lead to test failure.

Why handler is called twice? Is it a bug of @vue/test-utils?

PS. Removing any of the if statements from watcher, fixes the test. As well as removing immediate:true

Oleg Oshkoderov
  • 500
  • 1
  • 4
  • 17
  • That is the purpose of immediate : execute directly and when the value changed. For me it looks OK. Am I missing something ? – Sodala Dec 18 '19 at 13:19
  • Sorry, forget to mention that after `setProps` there is two calls to `handler`: first with value `'good'` and second with `undefined`. That's why test is failing. – Oleg Oshkoderov Dec 18 '19 at 13:54

0 Answers0