Reputation: 6715
I am trying to mock and spy on the redis set method in my nestjs setup, but I don't think that it is working as it should.
const mockRedis = {
set: jest.fn().mockResolvedValue(undefined),
};
const mockRedisService = {
getClient: jest.fn(() => mockRedis),
};
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
providers: [
{ provide: RedisService, useValue: mockRedisService },
],
}).compile();
});
it('...',() => {
const redisSetSpy = jest.spyOn(mockRedis, 'set');
myTestedMethod();
expect(redisSetSpy).toBeCalledWith(/* args here */);
})
I suspect that it is not possible to use spyOn with a nested method as set
in this context? How should I mock redis to be able to use spyOn on set
? The library used for redis in this case is nestjs-redis
.
Upvotes: 2
Views: 2421
Reputation: 4258
You don't have to use spyOn
to check the arguements that have been passed to the function. You can simply create a jest.fn()
:
let mockRedisSet;
// Function that creates the testing app.
const createApp = () => {
const mockRedis = {
set: mockRedisSet,
};
const mockRedisService = {
getClient: jest.fn(() => mockRedis),
};
const moduleRef = await Test.createTestingModule({
providers: [{ provide: RedisService, useValue: mockRedisService }],
}).compile();
};
// For each test, set default mock and create testing app.
beforeEach(async () => {
mockRedisSet = jest.fn().mockResolvedValue(undefined);
createApp();
});
describe("...", () => {
// For each sub tests, set default mock and create testing app.
beforeEach(async () => {
mockRedisSet = jest.fn().mockResolvedValue(/* Specific value for sub tests */);
createApp();
});
it("...", () => {
myTestedMethod();
// Check which arguments was passed to the mock function.
expect(mockRedisSet).toHaveBeenCalledWith(/* args here */);
});
});
Creating a mock is much simpler this way as you only have to create the mocked objects and test the functions the use.
Here your spy is mockRedisSet
and I reorganized your testing file so the spy function has a default value that can be overridden for specific tests. You have more control on the testing value and a default value reset for each tests so that tests don't interfer with each other.
Upvotes: 2