I have a function where I take a time range as input and fetch 2 rows from my db. I need to get the difference of the field between the 1st and last data entry in the given range.
My function
async getUsage(start: Date, id: number) {
const initial = await this.datarepo
.createQueryBuilder('data')
.where('data.deviceId = :id and data.RTC > :start')
.setParameter('id', id)
.setParameter('start', start)
.orderBy('data.RTC', 'ASC')
.getOne();
const final = await this.datarepo
.createQueryBuilder('data')
.where('data.deviceId = :id and data.RTC > :start')
.setParameter('id', id)
.setParameter('start', start)
.orderBy('data.RTC', 'DESC')
.getOne();
if (!final) return 0;
const usage = final.reading- initial.reading;
return usage;
}
When I try to mock the function, I am getting the same data for each call even when I use mockResolvedValueOnce()
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
DataService,
{
provide: getRepositoryToken(dataentity),
useValue: {
create: jest.fn(),
save: jest.fn(),
},
},
],
}).compile();
service = module.get<DataService>(DataService);
datarepo= module.get(getRepositoryToken(dataentity));
});
it('gives the difference between energy readings for the given time range', async () => {
datarepo.createQueryBuilder = jest.fn(() => ({
where: jest.fn().mockReturnThis(),
setParameter: jest.fn().mockReturnThis(),
orderBy: jest.fn().mockReturnThis(),
getOne: jest
.fn()
.mockResolvedValueOnce(usageStart)
.mockResolvedValueOnce(usageEnd),
}));
const result = await service.getUsage(new Date('2021-03-01T11:57:00.000Z'), 981);
expect(result).toEqual(5);
});
const usageStart = {
reading: 70,
RTC: '2021-03-01T11:57:45.000Z',
};
const usageEnd = {
reading: 75,
RTC: '2021-03-01T12:57:45.000Z',
};
I should get 5 as the result but I am getting 0
expect(received).toEqual(expected) // deep equality
Expected: 5
Received: 0
You mock datarepo.createQueryBuilder
as a function, the function will return an object with some mock functions include getOne
function.
You call this.datarepo.createQueryBuilder
two times, it will return 2 different instances of the object. Then, getOne
function always returns the first mock value - usageStart
, because it never is called again.
Let's create a mock object, then mock datarepo.createQueryBuilder
will return that object:
const queryBuilderMock = {
where: jest.fn().mockReturnThis(),
setParameter: jest.fn().mockReturnThis(),
orderBy: jest.fn().mockReturnThis(),
getOne: jest
.fn()
.mockResolvedValueOnce(usageStart)
.mockResolvedValueOnce(usageEnd),
}
datarepo.createQueryBuilder = jest.fn(() => queryBuilderMock);
As you see, datarepo.createQueryBuilder
always return queryBuilderMock
object.