0

I'm struggling with mocking a method when mocking an ES6 class, using MockedClass of the jest library.

Example:

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

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

The following works 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);
    });
}

But say I wanted to mock add to always return 5, no matter the input.

With jest.Mocked it's done like: MockedService.add.mockReturnValue(5) if I understand it correctly here. But how do I solve it when I've mocked a class?

EDIT: Ismail gave the option to mock the whole implementation in the jest.mock() invocation. However, in this case, ideally, I'd like to mock the implementation/return value for each test.

1
  • Can you show the code of implementation? How did you use the CalculatorService? Commented Aug 9, 2023 at 3:07

2 Answers 2

0

Here is a rough idea how I have mocked classes

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

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

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

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

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

    impementingClass.implimentation(1,2);
    expect(MockedCalculatorService.add).toHaveBeenCalledWith(1,2)
  });

}

Note - using npm i ts-jest

Sign up to request clarification or add additional context in comments.

1 Comment

Will test that. For this case though, Ideally I'd like to mock the implementation/return value for each test, not one implementation for all.
0

The following worked, by using jest.spyOn. Not well documented though, so I leave 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 my real case, it was an async function that I mocked, and then the following was necessary:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.