Reputation: 1622
here is the basic setup
component.js
import {functionIWantToMock, val} from "somewhere/on/my/hdd"
export function Component() {
return (<>
<div>{val}</div>
<div>{functionIWantToMock()}</div>
</>)
}
component.test.js
import { Component } from "./component";
import { render, screen } from "@testing-library/react";
it("should change the result of the function", () => {
// Change behaviour of functionIWantToMock
functionIWantToMock = () => {
return "empty"
}
render(<Component/>);
// This is not a proper assertion
expect(screen.getByRole("img")).toBeVisible()
})
I've looked at manual mocking, spying and jest.fn()
but none of those will work, i think, because the call is happening within the component and so I can't mock it globally.
What is the correct way to mock functionIWantToMock
so that i can change its behaviour in the component for the test?
Upvotes: 1
Views: 49
Reputation: 6529
You can either use module mocking or dependency injection for this.
The Jest docs have an example of mocking a module, you would need to do this:
component.test.js
import { Component } from "./component";
import { render, screen } from "@testing-library/react";
// This gives you a handle to the function so you can mock
// the return value, make expectations on it, etc
import { functionIWantToMock } from "somewhere/on/my/hdd";
// This mocks all exports from the module
jest.mock("somewhere/on/my/hdd");
it("should change the result of the function", () => {
// Change behaviour of functionIWantToMock
functionIWantToMock.mockReturnValue("empty");
render(<Component/>);
expect(functionIWantToMock).toBeCalled()
})
I recommend adding clearMocks: true
to your Jest config to avoid leaking state between tests.
Your other option is to pass the function into the component:
component.js
import {functionIWantToMock as defaultFn, val} from "somewhere/on/my/hdd"
// Using the import as the default function helps you avoid
// passing the function where this component is used.
export function Component({functionIWantToMock = defaultFn}) {
return (<>
<div>{val}</div>
<div>{functionIWantToMock()}</div>
</>)
}
component.test.js
import { Component } from "./component";
import { render, screen } from "@testing-library/react";
it("should change the result of the function", () => {
const mockFn = jest.fn(() => {
return "empty"
})
render(<Component functionIWantToMock={mockFn} />);
expect(mockFn).toBeCalled()
})
Upvotes: 1