I am having an issue setting up a unit test to determine that a function is called with the correct arguments. useAHook
returns function foo
which calls function bar
. The code looks like this
//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
}
I am trying to unit test this code using renderHook
and jest.spyOn
. I want to confirm that calling function foo
results in bar
being called with the correct arguments. My unit test looks like this
//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);
});
The result is that the test fails saying that spy
is never called. Am I doing something wrong here or using either tool incorrectly?
This line:
import * as myModule from './myModule.js'
...imports the module bindings for myModule.js
into myModule
.
Then this line:
const spy = jest.spyOn(myModule, 'bar');
...wraps the module export for bar
in a spy...
...but the spy never gets called because useAHook
doesn't call the module export for bar
, it just calls bar
directly.
If you modify useAHook
to call the module export for bar
then the spy will get called.
There are a couple of ways to do that.
You can move bar
into its own module...
...or you can import the module bindings for myModule.js
so you can call the module export for 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
}