【问题标题】:Jest / Unit test failing on the function which returns a asyncronous methodJest / 单元测试在返回异步方法的函数上失败
【发布时间】:2021-05-01 05:47:49
【问题描述】:

我正在使用 TypeORM。
使用真实数据库连接在本地运行良好。

但是当我用 Jest 运行测试时,测试失败了。
我模拟了我需要的 TypeORM 方法,并期望调用所有这些方法。

测试在expect(typeorm.getRepository(Covid).save).toHaveBeenCalled();上失败
它没有被调用。

我不明白为什么这个测试代码没有调用。

有人知道解决办法吗?

这里是代码。

describe('getCoronaData', () => {
  it('should get a Covid Status data and return it', async () => {
    typeorm.getRepository = jest.fn().mockReturnValue({
      findOne: jest.fn().mockResolvedValue(null),
      create: jest.fn(),
      save: jest.fn(),
    });

    await getCoronaData();

    expect(typeorm.getRepository).toHaveBeenCalledWith(Covid);
    expect(typeorm.getRepository(Covid).findOne).toHaveBeenCalled();
    expect(typeorm.getRepository(Covid).save).toHaveBeenCalled(); // this expect result is making an error
                                                                  // Expected number of calls: >= 1
                                                                  // Received number of calls:    0
  });
});

export const getCoronaData = async () => {
  try {
    // Just a fake data
    const covidStatus = [
      {
        city: 'city',
        totalCases: '100',
        increasedCases: '100',
        date: 'time',
      },
    ];
    const covidRepository = getRepository(Covid);
    covidStatus.forEach(async (status) => {
      const exist = await covidRepository.findOne({
        where: { city: status.city },
      });
      if (!exist) {
        // expecting save() method at this part to be called, but it fails
        return await covidRepository.save(
          covidRepository.create({
            city: status.city,
            totalCases: status.totalCases,
            increasedCases: status.increasedCases,
            date: status.time,
          })
        );
      } else {
        return await covidRepository.save([
          {
            id: exist.id,
            totalCases: status.totalCases,
            increasedCases: status.increasedCases,
            date: status.time,
          },
        ]);
      }
    });
  } catch (err) {
    console.error(err);
    return;
  }
};

【问题讨论】:

    标签: express testing jestjs


    【解决方案1】:

    自我回答

    我发现了测试失败的问题。 forEach() 方法不应与 async/await 一起使用。
    所以我只是使用 Promise.all()map() 更改了代码

    await Promise.all(
          covidStatus.map(async (status) => {
            const exist = await covidRepository.findOne({
              where: { city: status.city },
            });
            if (!exist) {
              const newData = covidRepository.create({
                city: status.city,
                totalCases: status.totalCases,
                increasedCases: status.increasedCases,
                date: $standardTime,
              });
              return covidRepository.save(newData);
            } else {
              return covidRepository.save([
                {
                  id: exist.id,
                  totalCases: status.totalCases,
                  increasedCases: status.increasedCases,
                  date: $standardTime,
                },
              ]);
            }
          })
        );
    

    或者

        for (const status of covidStatus) {
          const exist = await covidRepository.findOne({
            where: { city: status.city },
          });
          if (!exist) {
            const newData = covidRepository.create({
              city: status.city,
              totalCases: status.totalCases,
              increasedCases: status.increasedCases,
              date: $standardTime,
            });
            return covidRepository.save(newData);
          } else {
            return covidRepository.save([
              {
                id: exist.id,
                totalCases: status.totalCases,
                increasedCases: status.increasedCases,
                date: $standardTime,
              },
            ]);
          }
        }
    

    我从这里找到了这个解决方案。

    using forEach and async/await, behaves different for node and Jest

    【讨论】:

    • 异步测试通常需要一个 done() 函数调用作为测试的一部分。一旦你从一个 Promise 映射,这是不同的,但是没有那个,做一个基本的 async/await,应该有 done() 函数。
    猜你喜欢
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2020-07-14
    • 1970-01-01
    • 2021-01-29
    相关资源
    最近更新 更多