What is the best way to properly mock certain methods within a Jest class?

Imagine having a class structure like this:

located at ./src/myClass.ts

class myClass{

    methodA(){
    ...
    }

    methodB(){
    ...
    }
}

Now, let's say I need to mock method A. To do this, I created a file

./src/mocks/myClass.ts

class myClass{

    methodA(){
    ...
    }
}

After that, in ./tests/myClass.test.ts

'use strict';
import { myClass } from "../src/myClass";
jest.mock('../src/myClass');

describe('myClass', () => {
    it('returns methodB',  () => {
        const c = new myClass();
        //methodA is correctly mocked here
        c.methodA();
        // how do I make jest use the original method here?
        const data= c.methodB();

        expect(data)
          .toMatchObject({})
    }, 
    3000)
});

As stated in the comments above, I am struggling to access the original methodB.

My assumption is that I am mocking the entire class instead of mocking individual methods within the class. What is the best practice in jest to create a mock file that only mocks specific class methods?

Answer №1

__mocks__ directory or jest.mock - you have a choice to make. Let's explore an example using jest.mock:

myClass.ts:

export class myClass {
  methodA() {
    return 'real a';
  }

  methodB() {
    return 'real b';
  }
}

myClass.test.ts:

import { myClass } from './myClass';

jest.mock('./myClass', () => {
  const { myClass: originalMyClass } = require.requireActual('./myClass');
  const mMyClass = {
    methodA: jest.fn().mockReturnValueOnce('mock a'),
    methodB: originalMyClass.prototype.methodB,
  };
  return { myClass: jest.fn(() => mMyClass) };
});

describe('60633642', () => {
  it('mock should work for methodA', () => {
    const c = new myClass();
    const actual = c.methodA();
    expect(jest.isMockFunction(c.methodA)).toBeTruthy();
    expect(actual).toBe('mock a');
    expect(c.methodA).toBeCalledTimes(1);
  });

  it('original methodB should be called', () => {
    const c = new myClass();
    const actual = c.methodB();
    expect(jest.isMockFunction(c.methodB)).toBeFalsy();
    expect(actual).toBe('real b');
  });
});

After running the unit tests, here are the coverage results:

 PASS  stackoverflow/60633642/myClass.test.ts
  60633642
    ✓ mock should work for methodA (6ms)
    ✓ original methodB should be called (2ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |   85.71 |      100 |   66.67 |   83.33 |                   
 myClass.ts |   85.71 |      100 |   66.67 |   83.33 | 3                 
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.797s, estimated 9s

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

Is it possible to modify the number format of an input field while in Antd's table-row-edit mode?

I am currently utilizing the Table Component of Ant Design v2.x and unfortunately, I cannot conduct an upgrade. My concern lies with the inconsistent formatting of numbers in row-edit mode. In Display mode, I have German formatting (which is desired), but ...

The TypeScript compiler is generating node_modules and type declaration files in opposition to the guidelines outlined in the tsconfig.json file

For the past week, I've been trying to troubleshoot this issue and it has me completely puzzled. What's even more puzzling is that this app was compiling perfectly fine for months until this problem occurred seemingly out of nowhere without any c ...

The router's handler function sends back a collection of objects, but for some reason, the client is not receiving them in JSON format even though the response

I am currently developing an Express.js project using Typescript. In my project, I have defined an enum and an interface as follows: export enum ProductCategory { ELECTRONICS = 'electronics', CLOTHING = 'clothing', TOYS = & ...

Guide to developing a dynamic method while utilizing IntelliSense assistance

When utilizing itemsApi in React reduxTool kit, dynamic functions like use..., mutate... are generated. These dynamically created methods possess complete intelligence as well. For instance, if you have createApi({... getItems: builder.query<any, st ...

Changing an array into an object in JavaScript without rearranging the keys

I have a collection { 1: {id: 1, first: 1, last: 5} 2: {id: 2, first: 6, last: 10} 3: {id: 3, first: 11, last: 15} } My goal is to reverse the order of items without rearranging the keys so that it looks like this: { 1: {id: 3, first: 11, last: 15} 2: { ...

Discover an alternative to Events by harnessing the power of Observables to effectively listen for dismiss events in Angular Ionic

Currently, I am utilizing Ionic's inline modal feature that is activated by a boolean value. However, after the modal is closed, the boolean does not automatically reset to zero. The Ionic documentation suggests that developers should monitor the ionM ...

Creating a Personalized Color Palette Naming System with Material UI in TypeScript

I have been working on incorporating a custom color palette into my material ui theme. Following the guidance provided in the Material UI documentation available here Material UI Docs, I am trying to implement this feature. Here is an excerpt from my cod ...

Is it possible to use v-if in conjunction with a style tag to specify a different source file? Alternatively, is there a more efficient method I

I attempted the example provided below, but unfortunately, it did not function as expected. The reason behind my endeavor is that adding numerous modifiers (--tuned) to achieve the desired outcome seemed impractical. Therefore, I decided to try and link ...

Using CKEditor5 to Capture and Edit Key Presses

I'm currently working on capturing input from a CKEditor5 within an Angular application using TypeScript. While I am able to successfully display the CKEditor and confirm its presence through logging, I am facing difficulties in capturing the actual i ...

Inversify's Http Context consistently remains void of any content

Hello there, I'm in need of assistance with building an API using inversify and inversify-express-utils. Everything seems to be working fine with my controllers and the API so far, except for one issue. When trying to access the httpContext property i ...

Mixing a static class factory method with an instance method: a guide

After introducing an instance method addField in the code snippet below, I encountered an issue with the Typescript compiler flagging errors related to the static factory methods withError and withSuccess: The error message states: 'Property ' ...

Exploring the functionalities of express routes through JEST testing

I was eager to test the functionality of my express API endpoints using JEST. Take a look at my Express API code below: routs.ts // Get release notes routes.get('/release-notes', (req, res) => { request.get({ url: 'https://host.c ...

Module 'ngx-bootstrap' not found in project

My application is encountering an issue with ngx-bootstrap where the module can no longer be detected unless the path is specified. For instance: import { BsModalService, BsModalRef } from 'ngx-bootstrap'; results in "Cannot find module ' ...

The binding element 'params' is assumed to have a type of 'any' by default

I encountered an issue The binding element 'params' implicitly has an 'any' type. Below is the code snippet in question: export default function Page({ params }) { const { slug } = params; return ( <> <h1>{s ...

Determine the category of a container based on the enclosed function

The goal is to determine the type of a wrapper based on the wrapped function, meaning to infer the return type from the parameter type. I encountered difficulties trying to achieve this using infer: function wrap<T extends ((...args: any[]) => any) ...

Issue stemming from reactivity causing difficulties with Vuex data mutation within actions

I have a Vuex store action that needs to interact with the API using new data for updating purposes. My goal is to create a separate object that mirrors an existing value in the store, allowing me to manipulate it without affecting reactivity. However, w ...

Ways to turn off Typescript alerts for return statements

I'm looking to turn off this Typescript warning, as I'm developing scripts that might include return values outside of a function body: https://i.stack.imgur.com/beEyl.png For a better example, check out my github gist The compiled script will ...

Encountering an Invalid JSON error on the Developer console

I'm in the process of building a React application and aiming to establish a connection with my Back4App database. Within the Back4App dashboard, there exists a Person class containing data that needs to be retrieved. It appears that the call is being ...

Tips for utilizing the polymorphic feature in TypeScript?

One of the challenges I am facing involves adding data to local storage using a function: add(type: "point" | "object", body: FavouritesBodyPoint | FavouritesBodyObject) { // TODO } export interface FavouritesBodyPoint {} export in ...

Jasmine has detected an undefined dependency

Testing out the following code: constructor(drawingService: DrawingService) { super(drawingService); //... } private writeOnCanvas(): void { this.drawingService.clearCanvas(this.drawingService.previewCtx); this.drawing ...