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.
CodePudding user response:
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
CodePudding user response:
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)
);