vue开玩笑spyOn在计算watcher方法调用时不起作用

时间:2020-03-16 20:10:04

标签: vue.js jestjs vue-test-utils

我对玩笑和vue很熟悉,我想看看如何确保在更改道具时触发一种方法。在这种特定情况下,这是微不足道的,这似乎很简单。但这不起作用。

Components 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();
    })

笑话测试

        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 :(得分:1)

我希望还不晚。是的,jest.spyOn()和vue观察程序存在问题。我有一个解决该问题的技巧(仅在同步功能上测试过):

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属性的方法。