使用带有jest.spyOn的React钩子测试库时,未调用spy

bbmckpt7  于 2022-12-08  发布在  Jest
关注(0)|答案(3)|浏览(170)

我在设置单元测试以确定函数是否使用正确的参数调用时遇到问题。useAHook返回函数foo,该函数调用函数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
}

我尝试使用renderHookjest.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);
});

结果是测试失败,说明从未调用spy。我在这里做错了什么,或者错误地使用了其中的任何一个工具?

hrysbysz

hrysbysz1#

这一行:

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

...将myModule.js的模块绑定导入myModule
然后这行:

const spy = jest.spyOn(myModule, 'bar');

...将bar的 * 模块导出 * Package 在spy...
...但是spy永远不会被调用,因为useAHook不会调用bar的 * 模块导出 *,它只是直接调用bar
如果修改useAHook以调用bar的模块导出,则将调用spy。
有几种方法可以做到这一点。
您可以将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
}
qcbq4gxm

qcbq4gxm2#

我设法监视了钩子导出方法(使用import * as),然后将一个模拟函数注入到实现中:

import * as useThingHook from 'useThing'

it('a test', () => {
  const methodMock = jest.fn()
  jest.spyOn(useThingHook, 'usething').mockImplementation(() => ({
    method: methodMock
  }))

  act()

  expect(methodMock).toHaveBeenCalled()
})
pqwbnv8z

pqwbnv8z3#

从'./...'中导入 * 作为myModule常量mockedFn = spyOn(myModule,“useSomething”)

相关问题