I am trying to mock the return value of a method of a class which is instantiated inside of the class I am testing, without it persisting the mocked value across the rest of the tests.
Here is a very basic demo I've put together:
Mystery.ts
export class Mystery {
private max = 10;
public getNumber(): number {
return Math.random() * this.max;
}
}
TestedClass.ts
import { Mystery } from './Mystery';
export class TestedClass {
public someMethod() {
const numberGenerator = new Mystery();
return numberGenerator.getNumber();
}
}
TestedClass.test.ts
import { Mystery } from './Mystery';
import { TestedClass } from './TestedClass';
jest.mock('./Mystery');
describe('TestedClass', () => {
beforeEach(jest.clearAllMocks);
it('should return the number 1000', () => {
// I want to have Mystery.getNumber() return 1000 for this test only.
Mystery.prototype.getNumber = jest.fn().mockReturnValue(1000);
// jest.spyOn(Mystery.prototype, 'getNumber').mockReturnValue(1000);
// Mystery.prototype.getNumber = jest.fn().mockReturnValueOnce(1000);
const provider = new TestedClass();
const result = provider.someMethod();
expect(result).toEqual(1000);
});
it('should return undefined', () => {
const provider = new TestedClass();
const result = provider.someMethod();
// Expects: undefined, Received: 1000
expect(result).toEqual(undefined);
});
});
As you can see from the test, I am seeing 1000
appear in the second test which I would like to avoid. In the real scenario all of the tests will likely need to mock the return value of Mystery.getNumber()
(in different ways) but I want to ensure that one test is not affecting another test as it could be now.
This current behaviour does make sense as I am changing the Mystery.prototype
but I'm not sure how to mock the value for individual test in any other way. I am also aware of using composition, which would help tremendously here, but I would like to avoid this for the sake of this question.
Mystery
rather than gettingTestedClass
to new one up; that would substantially reduce coupling and make it trivial to test.