如何为相同的功能笑话模拟不同的值?

how to mock different values for same function jest?

我有一个函数,我将一个时间范围作为输入并从我的数据库中获取 2 行。我需要获取给定范围内第一个和最后一个数据条目之间的字段差异。

我的函数

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;
  }

当我尝试模拟该函数时,即使我使用 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',
};

我的结果应该是 5,但我得到的是 0

 expect(received).toEqual(expected) // deep equality

    Expected: 5
    Received: 0

您将 datarepo.createQueryBuilder 模拟为一个函数,该函数将 return 一个具有一些模拟函数的对象包括 getOne 函数。

您调用 this.datarepo.createQueryBuilder 两次,它将 return 对象的 2 个不同实例。然后,getOne 函数总是 return 第一个模拟值 - usageStart,因为它永远不会被再次调用。

让我们创建一个模拟对象,然后模拟 datarepo.createQueryBuilder 将 return 该对象:

      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);

如你所见,datarepo.createQueryBuilder总是returnqueryBuilderMock对象。