我正在TripService
中测试此功能:
async createAndMapTrips<T extends ITripEntity>(
driver: DriverEntity,
entities: T[],
intervalInMinutes: number = 10,
): Promise<[TripEntity[], T[]]> {
const trips: TripEntity[] = [];
const [tripsDb] = await this.tripRepository.getAndCountTrips(driver, {
driverId: driver.driverId,
fromEndTime: moment.utc(entities[0].timestamp).subtract(intervalInMinutes, 'minutes').toISOString(),
toEndTime: moment.utc(entities[entities.length - 1].timestamp).add(intervalInMinutes, 'minutes').toISOString(),
});
this.logger.log(tripsDb);
return [
trips,
entities.map((entity: T, idx: number) => {
let trip: TripEntity = this.findLastTripWithinRangeFromEntity(trips, entity);
if (!trip) {
trip = this.findLastTripWithinRangeFromEntity(tripsDb, entity);
if (!trip) {
this.logger.log('Trip does not exist, creating new trip');
trip = this.tripRepository.create({
driver,
id: this.generateRandomTripId(),
startTime: moment.utc(entity.timestamp).toISOString(),
endTime: moment.utc(entity.timestamp).toISOString(),
});
}
trips.push(trip);
}
trip.endTime = moment.utc(entity.timestamp).toISOString();
entity.trip = trip;
return entity;
}),
];
}
private findLastTripWithinRangeFromEntity<T extends ITripEntity>(trips: TripEntity[], entity: T, intervalInMinutes: number = 10): TripEntity {
return findLast(
trips,
((t: TripEntity) =>
moment.utc(entity.timestamp).isSameOrAfter(moment.utc(t.startTime), 'milliseconds')
&& moment.utc(entity.timestamp).diff(moment.utc(t.endTime), 'minutes') <= intervalInMinutes),
);
}
这是我的测试
describe('TripService.createAndMapTrips()', () => {
const entities: ITripEntity[] = [
{ timestamp: '2019-05-07T11:10:00.000Z', trip: null },
];
const driver: DriverEntity = plainToClass(DriverEntity, {
id: 1,
driverId: 'one',
clientId: 'one',
});
const tripsDb: TripEntity[] = plainToClass(TripEntity, [
{ id: '1', startTime: '2019-05-07T10:50:00.000Z', endTime: '2019-05-07T11:01:00.000Z' },
// this should be selected as it is the last one according to time
{ id: '2', startTime: '2019-05-07T10:55:00.000Z', endTime: '2019-05-07T11:06:00.000Z' },
]);
const result: [TripEntity[], ITripEntity[]] = [
plainToClass(TripEntity, [
{ id: '2', startTime: '2019-05-07T10:55:00.000Z', endTime: '2019-05-07T11:10:00.000Z' },
]),
[{
timestamp: '2019-05-07T11:10:00.000Z', trip: plainToClass(TripEntity, {
id: '2',
startTime: '2019-05-07T10:55:00.000Z',
endTime: '2019-05-07T11:10:00.000Z',
}),
}],
];
it('should map existing trips if the trips already exist within the time range requested', async () => {
tripRepositoryMock.getAndCountTrips.mockReturnValue([[tripsDb], 2]);
const findLastTripWithinRangeFromEntity = jest.spyOn(TripService.prototype as any, 'findLastTripWithinRangeFromEntity');
findLastTripWithinRangeFromEntity
.mockReturnValue(plainToClass(TripEntity, {
id: '2',
startTime: '2019-05-07T10:55:00.000Z',
endTime: '2019-05-07T11:06:00.000Z',
}))
.mockReturnValueOnce(undefined);
await expect(service.createAndMapTrips(driver, entities)).resolves.toEqual(result);
expect(tripRepositoryMock.getAndCountTrips).toHaveBeenCalledTimes(1);
expect(tripRepositoryMock.getAndCountTrips).toHaveBeenCalledWith(driver, {
driverId: driver.driverId,
fromEndTime: moment.utc(entities[0].timestamp).subtract(10, 'minutes').toISOString(),
toEndTime: moment.utc(entities[entities.length - 1].timestamp).add(10, 'minutes').toISOString(),
});
expect(findLastTripWithinRangeFromEntity).toHaveBeenCalledTimes(2);
expect(findLastTripWithinRangeFromEntity).toHaveBeenNthCalledWith(1, [], entities[0]);
expect(findLastTripWithinRangeFromEntity).toHaveBeenNthCalledWith(2, tripsDb, entities[0]);
expect(findLastTripWithinRangeFromEntity).toHaveBeenCalledWith([], entities[0]);
expect(tripRepositoryMock.create).toHaveBeenCalledTimes(0);
});
});
我遇到以下错误:
● TripService › TripService.createAndMapTrips() › should map existing trips if the trips already exist within the time range requested
expect(jest.fn()).toHaveBeenNthCalledWith(expected)
Expected mock function first call to have been called with:
[]
as argument 1, but it was called with
[{"endTime": "2019-05-07T11:10:00.000Z", "id": "2", "startTime": "2019-05-07T10:55:00.000Z"}].
Difference:
- Expected
+ Received
- Array []
+ Array [
+ TripEntity {
+ "endTime": "2019-05-07T11:10:00.000Z",
+ "id": "2",
+ "startTime": "2019-05-07T10:55:00.000Z",
+ },
+ ]
415 | });
416 | expect(findLastTripWithinRangeFromEntity).toHaveBeenCalledTimes(2);
> 417 | expect(findLastTripWithinRangeFromEntity).toHaveBeenNthCalledWith(1, [], entities[0]);
| ^
418 | expect(findLastTripWithinRangeFromEntity).toHaveBeenNthCalledWith(2, tripsDb, entities[0]);
419 | expect(findLastTripWithinRangeFromEntity).toHaveBeenCalledWith([], entities[0]);
420 |
at Object.<anonymous> (trip/trip.service.spec.ts:417:49)
at fulfilled (trip/trip.service.spec.ts:4:58)
我显然是在设置模拟返回值,并且根据逻辑,对findLastTripWithinRangeFromEntity
的第一次调用应该使用[]
进行,而第二次调用tripsDb
进行调用,但是调用时会使用不同的方法值。
我似乎找不到原因。
任何帮助将不胜感激。
答案 0 :(得分:0)
不能100%确定这一点,但是我认为这与how the jest.spyOn method calls the function有关。出于某种原因,它可能两次都与对象一起调用它,但同样,并不是100%确定。