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

In Angular 17, is there a way to trigger a component's method when a Signal is modified?

Our component is designed to monitor signals from a Service: export class PaginationComponent { private readonly pageSize = this.listService.pageSize.asReadonly(); private readonly totalCount = this.listService.totalCount.asReadonly(); readonly pag ...

Using Typescript to replicate Object.defineProperties

Is there a way to emulate Object.defineProperties from JavaScript in Typescript? I am interested in achieving something similar using the syntax of Typescript: Object.defineProperties(someObject.prototype, { property: {get: function() { return v ...

Solve the TypeScript path when using jest.mock

I am currently in the process of adding unit tests to a TypeScript project that utilizes compilerOptions.paths. My goal is to mock an import for testing purposes. However, I have encountered an issue where jest is unable to resolve the module to be mocked ...

Guide on running PHP (WAMP Server) and Angular 2 (Typescript with Node.js) concurrently on a local PC

My goal is to create a Web app utilizing PHP as the server-side language and Angular 2 as the MVC framework. While researching Angular 2, I discovered that it is best practice to install Node.js and npm first since Angular 2 utilizes Typescript. Despite ha ...

There is an implicit 'any' type error binding element 'currency' in Graphql React Typescript

I am facing an issue with my code. I want to use the EXCHANGE_RATES in renderedExchangeRates, but I am receiving an error message saying "Error Message: Binding element 'currency' implicitly has an 'any' type." I understand that this is ...

Angular 7 throwing errors of undefined variables

I encountered an error message that says Property 'country' does not exist on type 'ViewComponent'. Did you mean 'country$'? I'm at a loss on how to resolve this issue. I understand that there is an undefined variable ca ...

The attribute 'data' is not found in the type 'IntrinsicAttributes & IProps'. Error code: ts(2322)

I encountered the following issue: Error: Type '{ data: never; }' is not compatible with type 'IntrinsicAttributes & IProps'. The property 'data' does not exist on the type 'IntrinsicAttributes & IProps'. import { ...

Deciphering the intricacies of AWS-Config Rules and Alterations in Configuration

Currently, I am utilizing the aws-cdk to create config rules for approximately 15 rules that we need to monitor and receive notifications on. Below is a snippet of the code for reference: // Code snippet showing the creation of multiple config rules My m ...

Using asynchronous functions in a loop in Node.js

Although this question may have been asked before, I am struggling to understand how things work and that is why I am starting a new thread. con.query(sql,[req.params.quizId],(err,rows,fields)=>{ //rows contains questions if(err) throw err; ...

How can a button click function be triggered in another component?

These are the three components in my dashboard.html <top-nav></top-nav> <sidebar-cmp></sidebar-cmp> <section class="main-container" [ngClass]="{sidebarPushRight: isActive}"> <router-outlet></router-outlet> & ...

Error: ngModel does not reflect dynamic changes in value

After calling a Spring service, I am receiving JSON data which is stored in the "etapaData" variable. 0: id: 266 aplicacao: {id: 192, nome: "Sistema de Cadastro", checked: false} erro: {id: 220, nome: "Falta de orçamento", checked: false} perfil: {id: 8, ...

Is there a way to determine the quantity of lines within a div using a Vue3 watcher?

Is it feasible to determine the number of text lines in a div without line breaks? I am looking to dynamically display or hide my CTA link based on whether the text is less than or equal to the -webkit-line-clamp value: SCRIPT: const isExpanded = ref(true ...

The MaterialTable component is indicating that there is no property called 'tableData' on the IPerson type

Incorporated an editable attribute to my MaterialTable component. Currently looking for a way to retrieve the index of updated or deleted items within the onRowUpdate and onRowDelete methods. To replicate the issue, refer to this minimal sandbox example: ...

limit the data types of values within an object using Typescript

When working with typescript, how can I define the type signature for a plain old javascript object that allows any key, but restricts the values to strings only? For example, {a:"foo"} and {b:"bar"} are considered valid values, while {a:[1,2,3]} and {b:3} ...

Generating dynamic components using React and TypeScript

Creating a multi-step form using a set of components can be tricky. One approach is to compile all the components into an array and then use the map() method to render them in sequence. const stepComponents = [ <SelectCoach/>, <SelectDate/> ...

incomplete constructor for a generic class

I have multiple classes that I would like to initialize using the following syntax: class A { b: number = 1 constructor(initializer?: Partial<A>) { Object.assign(this, initializer) } } new A({b: 2}) It seems to me that this ini ...

I am unable to refresh the table data in Angular

Here is the code that I am currently working with: I am facing an issue where my webpage is not updating its data after performing delete or any other operations. The user list is not being displayed in the data. Despite my attempts, I have been unable to ...

Connect ngx-time picker to form input in Angular

Currently, I have successfully implemented Angular material date pickers in my project, however, I am facing a challenge with integrating time pickers as it is not natively supported by Angular Material for version 8. To address this issue, I am utilizing ...

The functionality of Angular/Typescript class.name appears to fail during a production build

Using Angular 5, I encountered an unusual problem with the class.name property. We have a TypeScript function as shown below: export class ApiService { public list<T>(c: new(values: Object)=> T) { var cname = c.name; .... } } When ...

Leveraging Angular and HTML to efficiently transfer the selected dropdown value to a TypeScript method upon the user's button click

I am experiencing difficulty accessing the .value and .id properties in {{selectItem}} in order to send them back to the typescript for an HTTP post at a later time. Although there are no specific errors, I have encountered exceptions and have tried search ...