Simulated outcome of function call on a faked ES6 class

I've encountered a challenge with mocking a method while mocking an ES6 class using the MockedClass feature of the jest library.

For instance:

export default class CalculatorService {
  constructor() {
    // setup stuff
  }

  public add(num1: number, num2: number): number {
    return num1 + num2;
  }
}

The current approach is functioning as expected:

import CalculatorService from 'services/calculatorService';
jest.mock('services/calculatorService');
const MockedCalculatorService = CalculatorService as jest.MockedClass<typeof CalculatorService>;

describe('Tests', () => {

    test('Test flow with Calculator service', () => {
        // Arrange

        // Act
        implementation(1,2); // Where CalculatorService is used

        // Assert
        const mockServiceInstance = MockedService.mock.instances[0];
        expect(mockServiceInstance.add).toHaveBeenCalledWith(1,2);
    });
}

However, what if I want to mock the add method to always return 5 regardless of input?

Using jest.Mocked, it can be achieved with

MockedService.add.mockReturnValue(5)
based on my understanding mentioned here. But how can I implement this when dealing with a mocked class?

UPDATE: Ismail suggested the option to mock the entire implementation within the jest.mock() declaration. Nonetheless, in this scenario, I prefer to mock the implementation/return value for each individual test ideally.

Answer №1

Here is a basic example of how I have simulated classes

import { mocked } from 'ts-jest/utils';
import { CalculatorService } from 'services/calculatorService';

jest.mock('services/calculatorService', () => {
  return {
    CalculatorService: jest.fn().mockImplementation(() => {
      return {
        add: () => {},
      };
    })
  };
});

describe('Unit Tests', () => {
  const MockedCalculatorService = mocked(CalculatorService, true);

  beforeEach(() => {
   MockedCalculatorService.mockClear();
  });

  it('Test functionality with Calculator service', () => {
    const implementingClass = new ImplementingClass();
    expect(MockedCalculatorService).toHaveBeenCalledTimes(1);

    implementingClass.implementation(1,2);
    expect(MockedCalculatorService.add).toHaveBeenCalledWith(1,2)
  });

}

Note - ensure to use npm i ts-jest

Answer №2

I successfully implemented a solution using jest.spyOn in my code. Although the process wasn't well documented, I have decided to share it here for future reference.

describe('Tests', () => {

    test('Test flow with Calculator service', () => {
        // Arrange
        jest.spyOn(MockedCalculatorService.prototype,'add').mockReturnValue(5);

        // Act
        implementation(1,2); // Where CalculatorService is used

        // Assert
        const mockServiceInstance = MockedService.mock.instances[0];
        expect(mockServiceInstance.add).toHaveBeenCalledWith(1,2);
        expect(mockServiceInstance.add).toHaveReturnedWith(5);
}

In a more complex scenario, I had to deal with an asynchronous function that needed mocking. Here is how I approached it:

jest.spyOn(MockedCalculatorService.prototype,'add').mockResolvedValue(5);
expect(mockServiceInstance.getRelationsByNobbNrsAsync).toHaveReturnedWith(
    new Promise(() => 5)
);

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

Pattern for defining objects with indexes in Typescript

My data is structured as shown below: let equipment:Equipment = { "1": { "name": "abc", "data": 123 }, "2": { "name": "def", "data": 234 }, "3": { "name": "ghi", "data": 345 }, ... } Converting this into an array se ...

The debate between using backticks and colons in TypeORM queries

Lately, I've been crafting queries utilizing backticks const firstUser = await connection .getRepository(User) .createQueryBuilder("user") .where(`user.id = '${id}'`) .getOne(); However, in the typeorm documentatio ...

How can I conceal the word "null" within an Angular 2 input field?

Whenever there is a null value in the JSON, it ends up displaying in the input field. How do I go about hiding it so that only the name shows up instead? <div> <input type="hidden" name="roleUserHidden-{{roleIndex}}" #role ...

What is the method for specifying the type of a Custom Component in Typescript?

I have developed a custom React component called Title, which dynamically renders different HTML elements like h1, h2, h3, h4, h5, h6, span, or div based on the props provided to the component. Everything is working perfectly: No errors related to typescr ...

Expanding the property of an established type to a nested type

Let's talk about titles. Well, maybe not this one. I tried to come up with a good title, but it didn't work out as planned. In my coding journey, I have created a cool interface called DefaultTheme: export interface DefaultTheme { colors: ...

Retrieve the vertical distance of an element's top edge from the browser window

I'm currently working on a hook that calculates the offsetTop of an element. This is crucial for applying styles to make the header stick to the top. import { useState, useEffect } from 'react'; interface ElementPosition { left: number ...

I am experiencing slow load times for my Angular 2 app when first-time users access it, and I am seeking assistance in optimizing its speed

Below, you'll find a snippet from my app.ts file. I'm currently working with angular2, firebase, and typescript. I'm curious if the sluggish performance is due to the abundance of routes and injected files? The application functions smoot ...

Why does my Visual Studio Code always display "building" when I launch an extension?

https://code.visualstudio.com/api/get-started/your-first-extension I followed a tutorial to create a hello world extension. Why does my VSCode always display 'building' when I run the extension? Executing task: npm run watch < [email p ...

Using useRef as a prop in React with TypeScript

I am currently experimenting with TypeScript and encountering an issue when trying to use useRef in a custom element specifically when passing it as a prop I have attempted the following: import React from "react"; export interface InputProps extends ...

Retrieve the thousand separator for numbers using Angular in various languages

When using the English locale, numbers appear as follows: 111,111,222.00, with a comma as the thousand separator and a point as the decimal separator. In languages like German, the same number would be represented as 111.111.222,00, reversing the positions ...

Guide to setting the order of rendering in React applications

I am currently working with a .tsx file that renders two components: export default observer(function MyModule(props: MyModuleProps) { .... return ( <div> <TopPart></TopPart> <LowerPart>< ...

The specified property is not present on the given type

I am receiving data from an API, and I have defined its structure like this interface DailyData { dt: number; sunrise: number; sunset: number; moonrise: number; moonset: number; moon_phase: number; temp: {day: number, eve: number, max: number ...

Verify that a memoized component remains static and does not undergo a re-rendering process

After making a recent commit, I noticed a decrease in performance in my React app. It seems that introducing Context has caused issues with Memoization. I am interested in creating tests to confirm that a memoized component is not re-rendered after a user ...

Creating a global TypeORM connection allows you to easily access your

In my node.js application, I am utilizing typeorm with Typescript. My goal is to optimize the usage of a single database connection for all functions within a class rather than establishing a new connection in each function. The current setup involves crea ...

How can an Angular4 unit test disregard an HTML tag from a third-party component?

I've exhausted my resources by checking the docs, SO, and attempting various solutions, but I am unable to make this work. The issue arises when writing a unit test for an angular4 application using karma/jasmine. The test is targeting a component tha ...

Utilize the authenticated page across various tests in Playwright for efficient testing

Starting out fresh with playwright and node.js frameworks Currently in the process of developing a framework using playwright with typescript. Everything was smooth sailing until I reached the point where I needed to run my tests sequentially on the same ...

The absence of a 'body' argument in the send() json() method within the Next.js API, coupled with TypeScript, raises an important argument

Currently, I have set up an API route within Next.js. Within the 'api' directory, my 'file.tsx' consists of the following code: import type { NextApiRequest, NextApiResponse } from "next"; const someFunction = (req: NextApiReq ...

A guide on successfully sending parameters to Angular routes

Currently, I am delving into Angular and exploring various basic concepts such as routing, Observables (and subscribing to them), making HTTP requests, and utilizing routing parameters. One scenario I have set up involves sending a HTTP GET request to JSON ...

The Karma testing feature in Angular Quickstart encounters issues right from the start

When attempting to run karma tests after a clean install of the official Angular quickstart on Windows 10, I encountered an issue. Following a series of four commands, here is what happened: C:\projects\temp>git clone https://github.com/angul ...

Having issues with NGXS subscription not functioning properly when selecting a variable

Currently, I am working with Angular 11 and NGXS. One issue I am facing involves a subscription for a variable in the state. Here is the problematic subscription: @Select(state => state.alert.alerts) alerts$: Observable<any[]> ngOnInit(): void { t ...