Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

jest.mock factory doesn't work inside a test #10494

Closed
JaLe29 opened this issue Sep 9, 2020 · 6 comments
Closed

jest.mock factory doesn't work inside a test #10494

JaLe29 opened this issue Sep 9, 2020 · 6 comments

Comments

@JaLe29
Copy link

JaLe29 commented Sep 9, 2020

馃悰 Bug Report

According to this thread: #2582 it doesn't work.

To Reproduce

Create test for myTestFn which return mocked value.

Test file:

import { myTestFn } from './fn'
 
describe(('TEST'), () => {
	it(('node mock false'), () => {
		jest.mock('detect-node', () => false);
		myTestFn(); // will print constant
	});

	it(('node mock true'), async () => {
		jest.mock('detect-node', () => true);
		myTestFn(); // will print constant
	});
});

Fn file:

import isNode from 'detect-node';
export const myTestFn = () => console.log({isNode})

Expected behavior

Should print mocked value.

Expected behavior

It print current value (node=true)

envinfo

npx envinfo --preset jest
npx: installed 1 in 0.994s

  System:
    OS: macOS 10.15.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
  Binaries:
    Node: 12.18.3 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.8 - ~/Documents/git/node_modules/.bin/npm
  npmPackages:
    jest: ^26.4.2 => 26.4.2
@JaLe29 JaLe29 changed the title Mock peer it doesn't work jest.mock factory doesn't work inside a test Sep 9, 2020
@JeromeDeLeon
Copy link

Have you seen #764 and see if it can help you?

@JaLe29
Copy link
Author

JaLe29 commented Sep 9, 2020

@JeromeDeLeon Same problem with code from #764

@ParallelTask
Copy link

because thread 2582 is closed, posting the temporary solution for others

By using jest.mock and jest.spyOn, we can mock inside every test with different implementation

// Header.js
export function Header() {
  return (<div data-testid="header" className="App-header">I am header</div>);
}

// App.js
import { Header } from "./components/Header";
export function App() {
    return <Header />;
}

**Scenario 1- mocking inside every test**

// App.test.js
import { render, screen } from "@testing-library/react";
import { App } from "./App";

let mockHdrObj = { Header: () => <></>};
jest.mock("./components/Header", () => mockHdrObj);

describe("AppComponent", () => {

  it("App component with current mocked hdr", async () => {
    jest.spyOn(mockHdrObj, "Header").mockReturnValue(<div data-testid="header">Mocked Header</div>);
    render(<App />);
    const hdr = await screen.getByTestId("header");
    expect(hdr.innerHTML).toEqual("Mocked Header");
  });

  it("App component with original mocked hdr", async () => {
    jest.spyOn(mockHdrObj, "Header").mockRestore();
    render(<App />);
    const hdr = await screen.queryByTestId("header");
    expect(hdr).toBeNull();
  });
});

**Scenario 2- If you want to hold the original implementation for some test cases**

// PureJestMock.js
import * as hdrModule from "./components/Header";

var mockHdrObj = { Header: hdrModule.Header }; // if you still want to hold to the original implementation
jest.doMock("./components/Header", () => mockHdrObj); // just doMock which does not do hoisting
export default mockHdrObj;

// App.test.js
import { render, screen, waitFor } from "@testing-library/react";
import mockHdrObj from "./PureJestMock";
import { App } from "./App"; // You should import the testable component only after importing the above-mocked objects

describe("App Component", () => {

  it("App component with empty header", async () => {
    jest.spyOn(mockHdrObj, "Header").mockReturnValue(<></>);
    render(<App />);
    const hdr = await screen.queryByTestId("header");
    expect(hdr).toBeNull();
  });

  it("App component with mocked hdr", async () => {
    jest.spyOn(mockHdrObj, "Header").mockReturnValue(<div data-testid="header">Mocked Header</div>);
    render(<App />);
    const hdr = await screen.getByTestId("header");
    expect(hdr.innerHTML).toEqual("Mocked Header");
  });

  it("App jest component with actual hdr", async () => {
    jest.spyOn(mockHdrObj, "Header").mockRestore();
    render(<App />);
    const hdr = await screen.getByTestId("header");
    expect(hdr.innerHTML).toEqual("I am header");
  });
});

@SimenB
Copy link
Member

SimenB commented Oct 3, 2022

You cannot mock after the fact - you need to mock before importing.

describe('TEST', () => {
  it('node mock false', () => {
    jest.resetModules();
    jest.mock('detect-node', () => false);

    const {myTestFn} = require('./fn');

    myTestFn(); // will print constant
  });

  it('node mock true', async () => {
    jest.resetModules();
    jest.mock('detect-node', () => true);

    const {myTestFn} = require('./fn');

    myTestFn(); // will print constant
  });
});

If detect-node would have returned a function you could have changed its mock implementation, but you need to change the return value of the module itself. Which is why resetModules is needed so the module doesn't cache the old value.

@github-actions
Copy link

github-actions bot commented Oct 3, 2022

Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot closed this as completed Oct 3, 2022
@github-actions
Copy link

github-actions bot commented Nov 3, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants