I encountered an issue with Typescript Jest where it was unable to find the mock or mockReturnedValue functions on the types I

Let's test out this interesting class:

//RequestHandler.js
import axios, {AxiosInstance} from 'axios';
import settings from './settings';

const axiosHandler: AxiosInstance = axios.create({
  baseURL: 'http://localhost:8081',
});

export default class RequestHandler {
  public async getData<$ResponseType = any>(url: string): Promise<void> {
    const response = await axiosHandler.get(url);
    return response.data;
  }
}

While attempting to create a test file for this class, I encountered some challenges when it came to mocking axios. Despite trying various methods such as spyOn and automatic mocks, I couldn't get them to work effectively. Below is a snippet from the unsuccessful test file that has me puzzled:

// RequestHandler.test.js
import axios from 'axios';
import RequestHandler from './RequestHandler';

interface ITestDataStructure {
  content: string
}

jest.mock('axios');

describe('RequestHandler Testing', () => {
  it('should correctly utilize axios get with the specified relativeUrl', async () => {
    const mockedGet = jest.fn();

    axios.create.mockReturnValue({
      get: mockedGet
    });

    mockedGet.mockResolvedValueOnce({
      content: 'example'
    });

    const data = await new RequestHandler().getData<ITestDataStructure>('/someEndpoint');
    expect(mockedGet.mock.calls.length).toEqual(1);
    expect(data).toEqual({
      content: 'example'
    });
  });
});

Upon running the test, an error message is displayed -

 TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    src/services/RequestHandler.test.ts:15:18 - error TS2339: Property 'mockReturnValue' does not exist on type '(options?: AxiosRequestConfig | undefined) => AxiosInstance'.

    15     axios.create.mockReturnValue({

This error is understandable since the axios type definition doesn't include the 'mockReturnValue' method for 'create'. How can we inform TypeScript that jest has made changes in this case?

Answer №1

Transform the mock method into a jest.Mock, like so:

import axios from "axios"
import Request from "./Request";

// Set up an Axios mock
// Jest will hoist this above the imports, so order doesn't matter
// Refer to https://jestjs.io/docs/manual-mocks#using-with-es-module-imports
jest.mock("axios", () => ({
  create: jest.fn()
}))

// Customize the `create` mock method
(axios.create as jest.Mock).mockReturnValue({
  get: getMock
})

A simpler alternative is to utilize thejest.mocked()function

The mocked() tool wraps types of the source object and its deeply nested members with type definitions of Jest's mock function.

jest.mocked(axios.create).mockReturnValue({ get: getMock });

Answer №2

Building on the highest-rated response, I personally advocate for preserving type definitions during type casting. One way to achieve this is by rephrasing it as follows:

(fetch as jest.Mocked<typeof fetch>).request.mockReturnValue({
  post: postMock
});

Answer №3

To effectively replace the axios.create method, utilize a Jest mock function like this:

axios.create = jest.fn();

This will enable you to easily define its return value.

Answer №4

This particular scenario is related to a different library, yet it involves a similar task. Upon converting the import into

jest.Mocked<typeof MyImport>
, I found it necessary to directly assign mock functions to its properties rather than utilizing the mockReturnValue method. This alternative method proved to be effective.

import CustomLogger from '../../custom-logger'
import { configureUtilities } from './utilities'

jest.mock('../../custom-logger')
const mockCustomLogger = CustomLogger as jest.Mocked<typeof CustomLogger>

describe('configureUtilities', () => {
  describe('when custom logger functionality is available', () => {
    beforeEach(() => {
      mockCustomLogger.log = jest.fn()
    })
    it('integrates the custom logger utilities', () => {
      const utilities = configureUtilities()
      expect(utilities).toHaveLength(1)
    })
  })

  describe('when custom logger functionality is not available', () => {
    beforeEach(() => {
      mockCustomLogger.log = undefined
    })
    it('does not integrate the custom logger utilities', () => {
      const utilities = configureUtilities()
      expect(utilities).toHaveLength(0)
    })
  })
})

Answer №5

I successfully resolved this issue using axios-mock-adapter. It worked flawlessly for me and even proved to be useful for handling nested calls.

// src/request.ts
import axios from "axios";
export const axiosCreate = axios.create();
export async function someRequest(){
  axiosCreate.get("http://localhost/users");
}

// src/__test__/request.test.ts
import * as request from ".../request";
import MockAdapter from "axios-mock-adapter";
const mock = new MockAdapter(request.axiosCreate);
it("Testing mock", async () => {
  mock.onGet("http://locahost/users").reply(200, "ok");
  const resp = await request.someRequest();
  expect(resp).toEqual("ok");
});

Hopefully, this solution will benefit someone else in a similar situation.

Answer №6

import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

beforeEach(() => {
jest.resetAllMocks();
mockedAxios.get.mockResolvedValue({
data: []
});
});

The axios mock only worked for me using this approach.

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

The NavBar element is failing to update when the state changes

I have been working on developing a shopping cart feature. As I implemented a context and passed the state as a value to increment and decrement buttons in the cart, everything seemed to be functioning well with item counts adjusting accordingly. However, ...

Is it possible for an Interface's property to be a type that contains an array?

As I dive into the Angular code, I encountered a peculiar type for a property within an Interface named 'Origin' that has left me perplexed. Here's the snippet: export interface Origin { areaNum?: number; open?: { [key: stri ...

What is the reason behind eslint not permitting the rule option @typescript-eslint/consistent-type-imports?

Upon implementing the eslint rule, I configured it like this. module.exports = { rules: { "@typescript-eslint/consistent-type-imports": [ "error", { fixStyle: "inline-type-imports" ...

What steps can be taken to ensure that all object properties become reactive?

Let's dive into this simplified scenario: interface Pup { name: string; age: number; } const puppy: Pup = { name: 'Rex', age: 3, }; The goal here is to establish a reactive link for each attribute within the puppy object. The usua ...

Combining TypeScript and ReactJS with RequireJS: A guide to importing react-dom in TypeScript

I am currently working with TypeScript and React.js. Within Visual Studio 2015, I have set the project properties to use AMD as the module system for TypeScript build, meaning I am utilizing requirejs for importing modules. Within my main.tsx file, I am r ...

Unable to use console log in shorthand arrow function while working with Typescript

When debugging an arrow function in JavaScript, you can write it like this: const sum = (a, b) => console.log(a, b) || a + b; This code will first log a and b to the console and then return the actual result of the function. However, when using TypeSc ...

What steps do I need to take in order to set up InfluxDB with Nest

As a beginner in the world of software development, I am eager to expand my knowledge and skills. Has anyone had experience operating influxdb with nestjs? If so, I would greatly appreciate it if you could share your past experiences. Thank you for takin ...

"Error: The React TypeScript variable has been declared but remains

Seeking guidance on ReactTS. I'm puzzled by the undefined value of the variable content. Could someone shed light on why this is happening and how to assign a value to it for passing to <App />? The issue persists in both the index.tsx file and ...

Generate types based on properties of a nested interface dynamically

Consider the setup provided: enum FormGroups { customer = 'customer', address = 'address', } interface Customer { 'firstName': string; } interface Address { 'street': string; } interface SomeFormEvent { ...

Why do I keep getting an ExpressionChangedAfterItHasBeenChecked error after trying to update a random color in an

Is there a way to assign a random color from an array without causing the error message: "ExpressionChangedAfterItHasBeenChecked"? Even though the color of the chip changes quickly before the message appears, it seems like it's working. How can I reso ...

Excluding node modules when not included in tsconfig

Within my Angular project, there is a single tsconfig file that stands alone without extending any other tsconfigs or including any additional properties. Towards the end of the file, we have the following snippet: "angularCompilerOptions": { ...

Issue with Angular Reactive form: Checkbox checked property not binding correctly when the page initially loads

Looking to achieve Two-way data binding of Checkbox in Angular Reactive forms. After checking the checkbox, I am updating the 'isdateChkd' variable and storing it in the state. Despite the variable being set to TRUE, the checkbox does not get aut ...

Accessing Nested Arrays in Angular 8: Retrieving Data in HTML Template from Multiple Layers of Arrays

Hello there. I'm using an API that gives me the following data: (4) [{…}, {…}, {…}, {…}] 0: dueDate: "2018-03-26T00:00:00" priority: {priorityId: 1, priorityName: "Critical", priorityColor: "red"} statuses: Array(1) 0: ...

convert a JSON object into an array field

I am looking to convert a list of objects with the following structure: { "idActivite": 1, "nomActivite": "Accueil des participants autour d’un café viennoiseries", "descriptionActivite": "", "lieuActivite": "", "typeActivite": "", ...

Implementing a feature in ReactJS that allows users to upload multiple images in base64 format

I'm trying to develop an image uploader using base64 and I want the output as an array. However, I am encountering an issue where the array is coming out empty!. I suspect it might be due to an asynchronous problem. Any tips on how to incorporate asyn ...

Angular fixes corrupted Excel files

My current project involves using Angular to call an API and retrieve a byte[] of an Excel file. However, I am facing issues with the file becoming corrupted when I convert the byte[] to a file using blob. Can anyone offer assistance with this problem? M ...

What are the properties used in functional components of React?

Seeking guidance on passing React component props to another component: interface IMyComponent { props: Props<any> } const MyComponent: FC = ({ props }) => { } Previously, I attempted to utilize the React.Props type after consulting this que ...

incorrect implementation of react lifecycle phases

My Sharepoint Framework webpart includes a property side bar where I can choose a Sharepoint List, and it will display the list items from that list in an Office UI DetailsList Component. Although all REST calls are functioning properly during debugging, ...

The message "jest command not recognized" appears

My test file looks like this: (I am using create-react-app) import React from 'react'; import ReactDOM from 'react-dom'; import App from './components/Calculator'; import { getAction, getResult } from './actions/' ...

Utilizing *ngfor in Angular 7 to Group and Display Data

I currently have incoming data structured like this in my Angular application Visit this link to see the data format https://i.stack.imgur.com/jgEIw.png What is the best way to group and sort the data by State and County, and present it in a table as sh ...