The value returned by a mocked Jest function is ignored, while the implemented function is not invoked

Having an issue with mocking the getToken function within my fetchData method in handler.ts while working with ts-jest. I specifically want to mock the response from getToken to avoid making the axios request when testing the fetchData method. However, despite my efforts, I still see the "called getToken" console log when running the test.

I am aware that moving getToken to a separate file would solve this problem, but I am curious about why it isn't working in this scenario as it may occur frequently in the future.

export const getToken = async (params: {}): Promise<string> => {
  try {
    console.log("called getToken");
    const oauthResponse = await axios.post(`url`, params);
    return oauthResponse.data.token;
  } catch (e) {
    throw new Error("Exception caught getting token");
  }
};

export const fetchData = async (params: {}): Promise<any> => {
  try {
    console.log("called fetchData");
    const tokenValue = await getToken(params);
    const response = await axios.post(`url`, params, {
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer " + tokenValue,
      },
    });
    return response.data.body;
  } catch (e) {
    throw new Error("Exception caught");
  }
};

This is how my handler.test.ts file looks like:

import { fetchData, getToken } from "./handler";

...

  (getToken as jest.Mock).mockResolvedValue(mockedTokenValue);
  (axios.post as jest.Mock).mockResolvedValue(response);

  const result = await fetchData(params);

...

I've also attempted the following:

jest.mock(".handler", () => ({
  ...jest.requireActual("./handler"),
  getSFEToken: jest.fn().mockImplementation(() => {
    return "mocked_token";
  })
}));

Here are snippets of my jest.config.ts and tsconfig.json for reference:


import type { Config } from "jest";

const config: Config = {
  preset: "ts-jest",
  testEnvironment: "node",
};

export default config;

{
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "commonjs",
    "target": "es5",
    "sourceRoot": "src",
    "outDir": "dist",
    "noImplicitAny": false,
    ...
  ],
  ...
  }
}

Ps. I have referred to https://jestjs.io/docs/bypassing-module-mocks for guidance. Despite trying various mocking techniques and spies, the actual implementation of getToken is being called instead of the mocked value.

Answer №1

If you want to easily test something, one approach is to inject its external dependencies. Mocking the module globally is an option, but keep in mind that if your test function and the mocked function are within the same module (file), they will both be mocked.

For axios testing, make sure to import axios and use jest.mock('axios') in the test file.

In a specific scenario, you can modify fetchData to optionally accept getTokenFunction.

Here’s an example:


export const getToken = async (params: {}): Promise<string> {
  //....
}

export const fetchData = async (params: {}, getTokenFunction = getToken): Promise<any> {
  //real implementation
}

// Test file
import { fetchData } from "./handler";
import axios from "axios"

// Mock axios globally
jest.mock('axios');

// Necessary for response manipulation in each test
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe("Description of the test", () => {
  beforeEach(() => {
    // Reset all mocks before each test
    jest.resetAllMocks();
  });

  it("Test description", async () => {
    // Setup
    const mockedResponse = {};
    mockedAxios.post.mockResolvedValue(mockedResponse);
    const getTokenMock = jest.fn().mockResolvedValue("desired result");

    // Action
    await fetchData({}, getTokenMock);

    expect(getTokenMock).toHaveBeenCalledWith(mockedResponse);
  });
})

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

Comparing JSON objects with JavaScript models: A guide

Currently I'm working with angular 2 and I have an array of data. data: MyModel[] = [ { id: 1, name: 'Name', secondName: 'SecondName' } In addition, I have created the interface MyModel: interface MyModel { id: number, nam ...

Any ideas on how to extract binary data from PHP passthru using a JavaScript ajax request?

I am facing an issue with retrieving and playing an audio file from a server using JavaScript. The ajax call in my code doesn't seem to callback, and I'm not certain if I'm handling the audio correctly in JavaScript. Below is the PHP file t ...

Allow foreign characters with regex while excluding special symbols

While browsing, I came across this thread: Is there a regular expression to match non-English characters?. It provides a regex to remove foreign characters using the code snippet str = str.replace(/[^\x00-\x7F]+/g, "");. My goal is slightly diff ...

Parent's hover element

I am currently working with the following loop: <?php if( have_rows('modules') ): $counter = 0; while ( have_rows('modules') ) : the_row(); ?> <div class="col span_4_of_12 <?php if($counter == 0) { ?>firs ...

Problem with Angular: ng-show not constantly re-evaluating expression

Utilizing a variable named activeScope to manage the state and toggle between two forms. This variable updates its value when a tab is clicked, triggering changeScope. While the change in active states for the tab buttons registers correctly, the divs for ...

Difficulties with angular ui-router authentication problems

When setting notify to true, the login.html does not render - it shows up as a blank page. However, if set to false, I receive multiple errors in the console: RangeError: Maximum call stack size exceeded at $.resolve (angular-ui-router.min.js:1) a ...

Tips for managing boolean values in a JSON data structure

My JSON object is causing issues because it has True instead of true and False instead of false. How can I fix this problem? The code snippet below shows that obj2 is not working properly due to boolean values being capitalized. <!DOCTYPE html> < ...

Ideas and Recommendations for Building a Laravel and Vue.js Hybrid Structure for MPA/SPA Applications

Consider the innovative approach I've been pondering - a combination of MPA and SPA, where each page functions as a Single Page Application, yet still reloads when navigating from one page to another (e.g. index.blade.php to posts.blade.php) like a tr ...

Variable in Javascript file causing return value to be 'undefined'

I have encountered an issue with my JavaScript file. It is extracting data from a SharePoint list and displaying it on an HTML page, but one of the fields appears as 'undefined' even though I defined it initially. The problematic variable is &ap ...

Encountering a CORS error while attempting to initiate a Github API call on my Next App

I'm currently developing a Next.js React app with TypeScript and I am wondering if I need a server to make requests to the GitHub API. In my next.config.mjs file, as shown below, the only task my app needs is to fetch content from a file in a public r ...

I'm curious if there is a method in c3 js that allows for displaying additional x-axis values when zooming in

Is it possible to dynamically increase the x-axis culling values with the c3.js data visualization tool when zooming in? This functionality is provided by d3.js. How can we implement this feature using c3.js? ...

Consistent column heights within each row

I currently have Bootstrap implemented on my website and have integrated jQuery to adjust the height of each column to match the tallest one. However, the issue I am facing is that the height adjustment applies globally across the entire page, rather than ...

Individualize JavaScript clients for each module in ExpressJS

Exploring the modular folder structure demonstrated by tjholowaychuk in this video. Is there a way to include a distinct client-side JavaScript file within each module? Currently, all my client JS resides in the /assets/js folder, but having a separate JS ...

Testing with AngularJS involves running unit tests to check if functions without methods have been called

When working on unit testing my Angular app with Jasmine, I found it simple to confirm if a method of a function was called using this approach: spyOn($rootScope, "$emit"); expect($rootScope.$emit).toHaveBeenCalled(); However, I struggled to figure out h ...

Exploring the capabilities of chromaprint.js within a web browser

I'm currently in the process of developing a music streaming platform and I'm looking to include the chromaprint.js library for deduplication purposes. In my workflow, I utilize browserify and gulp. Despite the fact that the library claims it ca ...

What is the best way to retrieve a value from $http or $resource using this filter?

Within my HTML, I have a structure that looks like {{ i.userId | userName }}. Essentially, I am attempting to convert this into a name by utilizing a filter. However, I am encountering numerous challenges with the asynchronous function required to retrieve ...

`Need help setting the active class for a bootstrap navbar using Angular JS?`

In my bootstrap navbar, I have the following menu items: Home | About | Contact I'm looking to assign the active class to each menu item based on the current angular route. Specifically, how can I set class="active" when the angular route is at # ...

I have been working on creating a hangman game, and although I have figured out the logic behind it, I am experiencing an issue where it is not functioning properly. After inspect

I am currently working on a basic hangman game using only HTML and JavaScript. I have the logic in place, but it doesn't seem to be functioning correctly. When I inspected the element, it showed an error saying 'undefined toUppercase.' As a ...

Tips for managing the data type of a bound value through ngModel: preventing number distortion to string

I posted a query and managed to solve it. However, I observed that even though the provided data consists of objects defined like this: export interface GisPoint { e: number; n: number; } when a user inputs a value, the original content changes from { e: ...

Skip ahead button for fast forwarding html5 video

One of the features in my video player is a skip button that allows users to jump to the end of the video. Below is the HTML code for the video player: <video id="video1" style="height: 100%" class="video-js vjs-default-skin" controls muted autoplay=" ...