Struggling to simulate a named function being exported with jest / react-testing-library when rendering a page in nextjs

I have been attempting to mock a named imported function in a NextJS page, but so far all my efforts from various sources have been unsuccessful.

I tried to replicate this by using create-next-app with --example with-jest and minimal code as shown below:

In my pages/index.tsx:

import Head from 'next/head'
import { hello } from '../utils/greeter'

export default function Home() {
  return (
    <div>
      <Head>
        <title>Create Next App</title>
      </Head>

      <main>
        <h1>{hello()}</h1>
      </main>
    </div>
  )
}

The utils/greeter.ts file contains the named function I wish to mock/spyOn in the test cases:

export const hello = (): string => 'hello world';

Now, moving on to the test file __tests__/index.test.tsx:

import { render, screen } from '@testing-library/react'
import Home from '@/pages/index'

describe('Home', () => {
  it('renders unmocked greeting', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: 'hello world',
    })

    expect(heading).toBeInTheDocument()
  })
  it('renders mocked greeting', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: 'hello mock',
    })

    expect(heading).toBeInTheDocument()
  })
})

To change the mock implementation, add the following above the test cases:

jest.mock('../utils/greeter', () => ({
  __esModule: true,
  hello: () => 'hello mock'
})

This will modify the function correctly and make the second test case pass. However, the mock persists for all test cases, causing the first test case to fail.

I would like the ability to choose whether to use the real implementation or a mock implementation for each test case, and even utilize a spy for verification purposes.

Every time I attempt to replace the 'hello mock' string with a reference, such as

const mockFn = jest.fn()

And then try to override the return value in each test case, e.g.

mockFn.mockReturnValue('hello mock')

Both tests fail because it seems the hello() function is not returning the mocked values.

Suggestions have been made to use jest.spyOn(..), but since the function is not part of an object, I am encountering type errors with this approach.

If anyone can provide guidance on where I might be misunderstanding the jest mocking process or going wrong, it would be greatly appreciated!

Answer №1

Check out this sandbox example where both tests pass successfully.

There are two crucial components you must have:

  1. To begin, you should mock the module itself by using a mock function (jest.fn()) for hello.
jest.mock("../utils/greeter", () => ({
  __esModule: true,
  hello: jest.fn(() => "hello world"),
}));
  1. Next, in tests where you want hello() to return a different value, you will need to override it with one of the .mock*Once() functions. The jest.mocked() function does not perform any mocking on its own; it simply returns the input object but asserts it as a mocked type so that TypeScript recognizes its .mock*() functions. Failure to properly mock it will result in errors.
jest.mocked(hello).mockReturnValueOnce("hello mock");

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble getting the NextJS custom 404 page to display?

I've located the 404.tsx file in the apps/specificapp/pages/ directory, yet NextJS continues to show the default pre-generated 404 page. Could there be a misunderstanding on my part regarding the documentation, or is there some obstacle preventing me ...

Adjusting the state prevents the input fields from being updated

Encountering a problem where setting the const buyFormData results in updating the array but causing the rest of the code (which updates the Input Fields) to stop functioning. No javascript error is showing, the code just hangs there. In my child component ...

An unexpected error occurred in Nextjs 13: an Uncaught (in promise) SyntaxError was thrown due to an unexpected token "'<'" in the JSON data, making it invalid

At the moment, I am attempting to retrieve a response from my server component in Next.js 13. Here is the snippet of code I am working with: import db from "../../../../utils/db"; import Product from "../../../../models/Product"; import { NextResponse } ...

Jest identifies an open handle when working with an Express application

For quite some time now, I've been grappling with a particular issue. It all started when I was conducting basic integration tests using a MongoDB database. However, I've minimized the code to its simplest form. The only thing left running is a s ...

The useEffect hook may not function properly in a production build of NextJS

useEffect is behaving differently in development and production builds. Here is the code snippet: useEffect(() => { console.log("useeffect 1") return () => { console.log("useeffect 2") }; }, []) In development ...

Is it possible to use the React Context API within the getInitialProps, getServerSideProps, or getStaticProps functions

Is there a way to invoke an action creator using the React Context API within getInitialProps/getServerSideProps/getStaticProps of NextJs? When working with Redux and NextJs, it is straightforward to access the store and dispatch an action creator. Howeve ...

What is the best way to display or conceal an array object using a toggle switch?

I'm trying to implement a show/hide functionality for descriptions when toggling the switch. Additionally, I want the switch to be initially checked and only show the description of each respective result. However, my current code is displaying all de ...

Testing the number of times module functions are called using Jest

As someone who is relatively new to JavaScript and Jest, I am faced with a particular challenge in my testing. jest.mock('./db' , ()=>{ saveProduct: (product)=>{ //someLogic return }, updateProduct: (product)=>{ ...

What is a dynamic route that does not include a slash?

I currently have a Next.js application set up with an SSR component that includes routes like /product1232312321. Previously, my solution was to create two folders: one named product and another nested folder inside it called [id]. Then I would redirect f ...

Bring in a library exclusively for the backend to utilize in getInitialProps

My current setup In my project, I have implemented the use of getInitialProps in the _app.js file to pre-load data on the server side: import App from "next/app"; // The problematic import import nodeFetchCache from "node-fetch-cache" ...

The SWA command line interface emulator experiences a crash when SSL is enabled on the NextJS development server

While attempting to run the NextJS development server with SWA emulator, I encountered a crash after enabling SSL and making the first request. Strangely, if I do a static export of the NextJS site and use that folder with the emulator, everything works sm ...

Customize Metadata Efficiently with NextJS 13 - Eliminate Redundant Requests

Imagine you have a server-side component located in the app directory called page.js, which represents a person: export default async function Person({ params }) { const person = await getPerson(params.id); return ( <h1> {person. ...

Incorporating next-intl for fetching information from a Strapi backend

I'm currently working on a multilingual nextjs project that involves Server Side Generation. Internationalization has been set up using the next-intl library, and the backend is powered by a headless CMS called Strapi. Despite trying to fetch data usi ...

How to Access localStorage using NextJs getInitialProps

I have been working with localStorage token in my next.js application. I encountered an issue when trying to retrieve the localStorage on page getInitialProps as it always returns undefined. For example, Dashboard.getInitialProps = async () => { con ...

What is the best way to programmatically route or navigate to a specific route within a Next.js class component?

tag: In the process of creating my app with next.js, I primarily use functional components. The sole exception is a class component that I utilize to manage forms. Upon form submission, my goal is to redirect back to the home page. However, when I attemp ...

leveraging an array from a separate JavaScript file within a Next.js page

I am facing a situation where I need to utilize an array from another page within my Next.js project. However, it seems that the information in the array takes time to load, resulting in encountering undefined initially when trying to access it for title a ...

Encountering a parsing failure in the _app.js file of a new Next.js project: Unexpected token

When starting a new Next.js project, I use the following command: npx create-next-app After moving into the project folder and running npm run dev, I encounter the following error: C:/Users/mikke/Documents/Projects/next-project/pages/_app.js 4:9 Module pa ...

Breaking the CORS policy for images in Next.js can be achieved by implementing certain methods and

I am currently working on a project in nextjs where I am utilizing the <Image /> component from next/image. The images are being fetched from a CDN hosted on a digitalOcean server. However, there seems to be an issue with the CORS policy for the CDN ...

Whenever I try to access the API path on localhost:1337/auth/local in Strapi, I always get a "not found"

After setting up a new Strapi project, I attempted to authenticate the API using JWT tokens. However, whenever I try to access the auth/local endpoint, it always returns a "not found" error message. ...

Creating a personalized menu using Nextron (electron) - Step by step guide

I'm currently in the process of developing an app with Nextron (Electron with Nextjs and Typescript). Although I have the foundation of my Next app set up, I've been encountering issues when attempting to create a custom electron menu bar. Every ...