在 jest.spyOn 中使用 react-hooks-testing-library - 不调用 spy

Sco*_*ott 4 jestjs react-hooks-testing-library

我在设置单元测试以确定使用正确参数调用函数时遇到问题。useAHook返回foo调用 function 的函数bar。代码看起来像这样

//myModule.js
export const useAHook = (arg1, arg2) => {
  const foo = useCallback(() => {
    bar(arg1, arg2);
  }, [arg1, arg2]);

  return foo;
}

export const bar = (a, b) => {
   //does some stuff with a and b
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用renderHookand对这段代码进行单元测试jest.spyOn。我想确认调用函数会foo导致bar使用正确的参数调用。我的单元测试看起来像这样

//myModule.spec.js

import * as myModule from './myModule.js'

it('should call foo with correct arguments', () => {
  const spy = jest.spyOn(myModule, 'bar');
  const { result } = renderHook(() => myModule.useAHook('blah', 1234));
  const useAHookFunc = result.current;

  useAHookFunc();

  // fails, spy is not called
  expect(spy).toBeCalledWith('blah', 1234);
});
Run Code Online (Sandbox Code Playgroud)

结果是测试失败,说spy从未调用过。我在这里做错了什么还是错误地使用了任一工具?

Bri*_*ams 7

这一行:

import * as myModule from './myModule.js'
Run Code Online (Sandbox Code Playgroud)

...导入myModule.jsinto的模块绑定myModule

然后这一行:

const spy = jest.spyOn(myModule, 'bar');
Run Code Online (Sandbox Code Playgroud)

...包裹模块出口bar一个间谍?

...但是 spy 永远不会被调用,因为useAHook它没有调用模块 export for bar,它只是bar直接调用。


如果您修改useAHook为调用模块导出,bar那么间谍将被调用。

有几种方法可以做到这一点。

你可以bar进入它自己的模块......

...或者您可以导入模块绑定,myModule.js以便您可以调用模块导出bar

import { useCallback } from 'react';

import * as myModule from './myModule';  // <= import the module bindings

export const useAHook = (arg1, arg2) => {
  const foo = useCallback(() => {
    myModule.bar(arg1, arg2);  // <= call the module export for bar
  }, [arg1, arg2]);

  return foo;
}

export const bar = (a, b) => {
   //does some stuff with a and b
}
Run Code Online (Sandbox Code Playgroud)