So I have a class which has a function. Inside this function, I execute another function from a library's class object which has a callback function. Inside that callback function, there's a method that I need to spy into. Is there any way to do that? Here's the rough detail:
export class Consume {
private readonly consumer: Consumer; // class from the library
private readonly randomService: RandomService; // class that it's method I want to spy on
constructor() {
this.consumer = new Consumer();
this.randomService = new RandomService();
}
consume(): void {
this.consumer.consume(async data => {
...
this.randomService.doSomething('withParam'); // I need to spy here on this method
...
})
}
}
I've tried mocking, but don't seem to work, here's what I have tried:
it('should do something', () => {
const consumerSpy = jest.spyOn(consumer, 'consume');
consumerSpy.mockImplementation(cb => {
cb(['data1', 'data2'])
}); // mocking the library's function
const randomServiceSpy = jest.spyOn(randomService, 'doSomething')
expect(randomServiceSpy).toBeCalledTimes(1); // Number of times called: 0 returned
});
and also this:
it('should do something', () => {
jest.mock('path/to/consume-class', () => {
consume: jest.fn()
}); // mocking Consume's consume function
consume.consume(); // calling consume function from Consume class above
const randomServiceSpy = jest.spyOn(randomService, 'doSomething')
expect(randomServiceSpy).toBeCalledTimes(1); // Number of times called: 0 returned
});
Any help would be appreciated! :)
CodePudding user response:
You can use install spy on Class.prototype.method
via jest.spyOn()
.
E.g.
consume.ts
:
import { Consumer } from './lib';
import { RandomService } from './random.service';
export class Consume {
private readonly consumer: Consumer;
private readonly randomService: RandomService;
constructor() {
this.consumer = new Consumer();
this.randomService = new RandomService();
}
consume(): void {
this.consumer.consume(async (data) => {
this.randomService.doSomething('withParam');
});
}
}
lib.ts
:
export class Consumer {
consume(fn) {
fn();
}
}
random.service.ts
:
export class RandomService {
doSomething(param) {}
}
consume.test.ts
:
import { Consume } from './consume';
import { Consumer } from './lib';
import { RandomService } from './random.service';
describe('71246273', () => {
afterEach(() => {
jest.restoreAllMocks();
});
test('should pass', () => {
jest.spyOn(Consumer.prototype, 'consume').mockImplementation((fn) => fn());
const doSomethingSpy = jest.spyOn(RandomService.prototype, 'doSomething');
const consume = new Consume();
consume.consume();
expect(doSomethingSpy).toBeCalledWith('withParam');
});
});
Test result:
PASS stackoverflow/71246273/consume.test.ts (8.765 s)
71246273
✓ should pass (3 ms)
-------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files | 90.91 | 100 | 83.33 | 90 |
consume.ts | 100 | 100 | 100 | 100 |
lib.ts | 50 | 100 | 0 | 50 | 3
random.service.ts | 100 | 100 | 100 | 100 |
-------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.879 s