计算观察者方法调用时,vue jest spyOn 不起作用

cph*_*pot 5 vue.js jestjs vue-test-utils

我越来越熟悉 jest 和 vue,我想看看如何确保在 prop 更改时触发方法。在这种特殊情况下,这很简单,而且看起来很简单。但它不起作用。

组件观察器

@Watch("id")
    public async idChanged() {
        this.calculateStatus();
    }
Run Code Online (Sandbox Code Playgroud)

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();
    })
Run Code Online (Sandbox Code Playgroud)

玩笑测试

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

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

        await wrapper.vm.$nextTick();

        expect(calculateFired).toBeCalled();
Run Code Online (Sandbox Code Playgroud)

我希望间谍增加呼叫计数器,但事实并非如此。它保持为零。如果我手动调用 wrapper.vm.calculateStatus(),间谍工作正常。所以 setProps 要么根本没有触发观察者,要么发生了一些奇怪的参考事件,导致在观察者中调用的方法不是我正在监视的方法。我不确定是哪个。

Lyo*_*lux 6

我希望现在还不算太晚。是的,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;
};
Run Code Online (Sandbox Code Playgroud)

然后在你的测试中:

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();
});
Run Code Online (Sandbox Code Playgroud)

如果immmediate需要该属性,您始终可以将其添加为 的参数insertSpyWatcherimmediate我没有找到获得原始观察者财产的方法。