I need to mock my custom hook when unit testing React component. I have read few tutorials and stackoverflow answers to this simple task, but without luck to implement it correctly.
My simplest possible setup for single test is as following:
// TestComponent.js
import React from "react";
import useTest from "./useTest";
const TestComponent = () => {
const { state } = useTest("initial_value");
return <div>{state}</div>;
};
export default TestComponent;
// useTest.jsx - simple custom hook
import React, { useState } from "react";
const useTest = (initialState) => {
const [state] = useState(initialState);
return { state };
};
export default useTest;
// TestComponent.test.jsx - my test case
import React from "react";
import { render } from "@testing-library/react";
import TestComponent from "./TestComponent";
jest.mock("./useTest", () => ({
useTest: () => "mocked_value",
}));
test("rendertest", () => {
const component = render(<TestComponent />);
expect(component.container).toHaveTextContent("mocked_value");
});
So I trying to mock useTest
custom hook to return "mocked_value", instead of "initial_value" from real custom hook. But above code just gives me this error:
TypeError: (0 , _useTest.default) is not a function
3 |
4 | const TestComponent = () => {
> 5 | const { state } = useTest("initial_value");
| ^
6 |
7 | return <div>{state}</div>;
8 | };
I have also tried:
import useTest from './useTest';
// ...
jest.spyOn(useTest, "useTest").mockImplementation(() => "mocked_value");
import useTest from './useTest';
// ...
jest.spyOn(useTest, "useTest").mockReturnValue("mocked_value");
But both gives me error Cannot spy the useTest property because it is not a function; undefined given instead
.
How do I implement this test?
to call jest. mock with the module name and the function to mock the useClientRect hook with a function that returns the mocked values of the hook. import * as hooks from 'module_name'; it('a test', () => { jest. spyOn(hooks, 'useClientRect').
Testing React Hooks with Jest and Enzyme. Jest and Enzyme are tools used for testing React apps. Jest is a JavaScript testing framework used to test JavaScript apps, and Enzyme is a JavaScript testing utility for React that makes it easier to assert, manipulate, and traverse your React components' output.
If you need to mock a global variable for all of your tests, you can use the setupFiles in your Jest config and point it to a file that mocks the necessary variables. This way, you will have the global variable mocked globally for all test suites.
import { renderHook, act } from '@testing-library/react-hooks'; import useCounter from '../hooks/useCounter'; describe('useCounter', () => { test(`Default value of `count` will be zero`, () => { const { result } = renderHook(() => useCounter()); expect(result. current. count). toBe(0); }); });
to mock the useClientRect hook and return the mocked return values with mockImplementation. We can just mock the return values since hooks are pure functions so they don’t commit side effects. To mock React custom hook returned value with Jest, we can call jest.mock.
The first method is mocking our hook at the top level of our test. Doing so will make this mocking enabled for all tests within this file. We are using jest.mock to do the mocking. As a first parameter, it’s taking the path to the file to mock.
*This post assumes you already have Jest configured in your application. I was using a custom hook in a component that needed to be mocked out in order to properly produce a snapshot test. I chose to mock the this particular function because it was dependent on a part of the DOM that was not available for the hook to be operational.
I was using a custom hook in a component that needed to be mocked out in order to properly produce a snapshot test. I chose to mock the this particular function because it was dependent on a part of the DOM that was not available for the hook to be operational.
I'm answering to myself. This way it's working:
jest.mock("./useTest", () => ({
useTest: () => ({ state: 'mocked_value' }),
}));
And if I want to use default export in custom hook:
jest.mock("./useTest", () => ({
__esModule: true,
default: () => ({ state: 'mocked_value' }),
}));
Also, if I want to also use setState
method in my hook and export it, I can mock it like this:
const mockedSetState = jest.fn();
jest.mock("./useTest", () => ({
useTest: () => ({ state, setState: mockedSetState }),
}));
And now it's possible to check if setState
has been called once:
expect(mockedSetState).toHaveBeenCalledTimes(1);
Since you use export default useTest
in useTest module, it expects to get that function reference from a default attribute in your mock.
Try this:
jest.mock("./useTest", () => ({
default: () => "mocked_value",
}));
If you want to avoid confusion, you could try export const useTest = ...
in useTest module and then import { useTest } from './useTest'
in your component. No need to change your test if using this approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With