vue jest spyOn не работает при расчете вызовов метода наблюдателя - PullRequest
1 голос
/ 16 марта 2020

Я знакомлюсь с шуткой и vue, и я хотел посмотреть, как сделать так, чтобы метод срабатывал при смене пропеллера. В этом конкретном сценарии это тривиально, и это казалось прямым. Но это не работает.

Компонент Watcher

@Watch("id")
    public async idChanged() {
        this.calculateStatus();
    }

beforeEach - запускает оболочку для каждого теста

beforeEach(async () => {
        var httpClient = new PemHttpClient(vue);
        var v3ReferenceDatumService = new V3ReferenceDatumService(httpClient, "");
        var contractService = new V3ContractService(httpClient, "", v3ReferenceDatumService);

        wrapper = mount(AmendmentIdDisplay, {
            provide: {
                v3ContractService: contractService,
            },
            propsData: {
                id: "82.5.1"
            }
        });

        await wrapper.vm.$nextTick();
    })

Jest Test

        let calculateFired = jest.spyOn(wrapper.vm, "calculateStatus");

        wrapper.setProps({
            ...wrapper.props(),
            id: "1"
        })

        await wrapper.vm.$nextTick();

        expect(calculateFired).toBeCalled();

Я ожидаю увеличил счетчик вызовов, но это не так. Осталось на нуле. Если я вручную вызываю wrapper.vm.calculateStatus (), шпион работает правильно. Таким образом, setProps либо вообще не запускает наблюдателя, либо происходит какая-то странная ссылочная вещь, которая заставляет метод, который вызывается в наблюдателе, не быть методом, за которым я слежу. Я не уверен, какой.

1 Ответ

0 голосов
/ 06 апреля 2020

Надеюсь, еще не поздно. Да, есть проблема с наблюдателями jest.spyOn () и vue. У меня есть трюк, который исправляет проблему (проверено только на функции syn c):

const insertSpyWatcher = (vueInstance: any, watcherExpression: string, spyInstance: jest.SpyInstance) => {
  let oldWatcherIndex = -1;
  let deep = false; // pass the deep option value from the original watcher to the spyInstance

  // find the corresponding watcher
  vueInstance._watchers.forEach((watcher: any, index: number) => {
    if (watcher.expression === watcherExpression) {
      oldWatcherIndex = index;
      deep = watcher.deep;
    }
  });

  // remove the existing watcher
  if (oldWatcherIndex >= 0) {
    vueInstance._watchers.splice(oldWatcherIndex, 1);
  } else {
    throw new Error(`No watchers found with name ${watcherExpression}`);
  }

  // replace it with our watcher
  const unwatch = vueInstance.$watch(watcherExpression, spyInstance, { deep });
  return unwatch;
};

Затем в вашем тесте:

it('test the watcher call', () => {
  let calculateFired = jest.spyOn(wrapper.vm, "calculateStatus");
  insertSpyWatcher(wrapper.vm, "id", calculateFired) // Yes 'id' is the name of the watched property
  wrapper.setProps({
    ...wrapper.props(),
    id: "1"
  })
  await wrapper.vm.$nextTick();
  expect(calculateFired).toBeCalled();
});

Если свойство immmediate необходимо, вы всегда можете добавить его в качестве аргумента insertSpyWatcher. Я не нашел способа получить свойство immediate исходного наблюдателя.

...