I'm trying out nestjs and jest on a personal project. And I'm having issues figuring out how to properly use the expect().toHaveReturnedWith()
methods.
Or maybe the problem is with the way I define the resolved value: jest.spyOn(subscriptionsHistoryRepository, 'findAll').mockResolvedValue([mockRecords, 2])
? Although, debugging the test I can see that the .findAll()
returns the mockRecords as I expected.
This is the bit of the code that I'm implementing:
describe('SubscriptionsModule', () => {
describe('GetSubscriptionHistoryService', () => {
let service: GetSubscriptionHistoryService;
let subscriptionsHistoryRepository: SubscriptionsHistoryRepository;
beforeAll(async () => {
const moduleRef: TestingModule = await Test.createTestingModule({
providers: [
GetSubscriptionHistoryService,
{
provide: SubscriptionsHistoryRepository,
useValue: {
findAll: jest.fn(),
},
},
],
}).compile();
service = moduleRef.get<GetSubscriptionHistoryService>(GetSubscriptionHistoryService);
subscriptionsHistoryRepository = moduleRef.get<SubscriptionsHistoryRepository>(
SubscriptionsHistoryRepository,
);
});
afterEach(() => {
jest.resetAllMocks();
});
it('Should hava all class instances defined', () => {
expect(service).toBeDefined();
expect(subscriptionsHistoryRepository).toBeDefined();
});
it("Should return the subscription's status history", async () => {
jest.spyOn(subscriptionsHistoryRepository, 'findAll').mockResolvedValue([mockRecords, 2]);
await service.execute(CUSTOMER_ID, SUBSCRIPTION_ID, 1);
expect(subscriptionsHistoryRepository.findAll).toHaveBeenCalledTimes(1);
expect(subscriptionsHistoryRepository.findAll).toHaveBeenCalledWith({
where: {
customerId: CUSTOMER_ID,
subscriptionId: SUBSCRIPTION_ID,
},
take: 5,
skip: 0,
order: {
createdAt: 'DESC',
},
});
expect(subscriptionsHistoryRepository.findAll).toHaveReturnedWith([mockRecords, 2]);
});
});
});
Test Results:
expect(jest.fn()).toHaveReturnedWith(expected)
Expected: [[{"createdAt": 2023-11-30T02:02:51.982Z, "customerId": "f1e8fc48-4780-45e4-858b-9e15b3382db5", "deletedAt": null, "extProviderStatus": "trialing", "id": "2e4c42b1-3d46-4438-bc68-64de46aa16d0", "status": "started", "subscriptionId": "2e4c42b1-3d46-4438-bc68-64de46aa16d5", "updatedAt": 2023-11-30T02:02:51.982Z}, {"createdAt": 2023-11-30T02:02:51.982Z, "customerId": "f1e8fc48-4780-45e4-858b-9e15b3382db5", "deletedAt": null, "extProviderStatus": "active", "id": "2e4c42b1-3d46-4438-bc68-64de46aa16d1", "status": "active", "subscriptionId": "2e4c42b1-3d46-4438-bc68-64de46aa16d5", "updatedAt": 2023-11-30T02:02:51.982Z}], 2]
Received: {}
All the other assertions work nice, but the expect(subscriptionsHistoryRepository.findAll).toHaveReturnedWith([mockRecords, 2])
line returns a empty object {}
.
I've debugged the test run and I can see that the spyOn.mockResolved worked fine, though. Not sure of what am I missing and why this assertion is failing.
The problem is that subscriptionsHistoryRepository.findAll
returns a promise.
So the expectation is comparing a promise with the array. Also bear in mind that toHaveReturnedWith
uses strict equality (===
), so you must have the exact same result.
expect(subscriptionsHistoryRepository.findAll).toHaveReturnedWith([mockRecords, 2]);
You can fix this with something like
const expectedPromise = Promise.resolve([mockRecords, 2]);
jest.spyOn(subscriptionsHistoryRepository, 'findAll').mockValue(expectedPromise);
[...]
expect(subscriptionsHistoryRepository.findAll).toHaveReturnedWith(expectedPromise);
I have to say that I never had to use something like toHaveReturnedWith
in a unit test. In this case in particular, I don't think that expectation adds anything to the test. The assertion expect(subscriptionsHistoryRepository.findAll).toHaveBeenCalledWith([...])
is all you need.