检查是否在单元测试中调用了函数

时间:2017-11-16 14:25:09

标签: javascript node.js unit-testing jestjs

您好我试图在Jest中为我编写的模块编写一些单元测试,但目前有些困难,需要一些建议如何继续。

export const submitOrder = async (body, key) => {
  const clientRepo = new ClientRepository(db)
  const companyRepo = new CompanyRepository(db)

  const company = await getCompanyByKey(
    companyRepo,
    key
  );

  const client = await createClient(
    clientRepo,
    body
  );

  await addClientToCompany(
    companyRepo,
    client.id,
    company.id
  );

  .. More things
}

我可以通过传递模拟的存储库轻松测试每个函数(getCompanyByKeycreateClientaddClientToCompany)。

但我也想测试我的"流程"通过检查我的存储库函数是否已被调用,submitOrder函数。但是我需要每个存储库的实例,在我的submitOrder函数之前我不会实例化。

像这样的东西,这与我对我的功能进行单元测试的方式类似。

jest.mock('../repositories/ClientRepository');
jest.mock('../repositories/CompanyRepository');

test('should be able to submit an order', async () => {
  const apiKey = 'mocked-super-key';
  const body = getMockData();

  const result = await submitOrder(body, apiKey);
  expect(result).toMatchSnapshot();
  expect(CompanyRepository.findByKey).toHaveBeenCalled();
  expect(ClientRepository.create).toHaveBeenCalled();
  expect(CompanyRepository.addClient).toHaveBeenCalled();
});

您是否有任何关于如何测试我的存储库是否已被调用的提示?

2 个答案:

答案 0 :(得分:1)

您描述的问题是依赖注入背后的激励因素之一。

作为一个示例:您的submitOrder()代码使用new直接实例化特定实现ClientRepository的客户端存储库。相反,它可以声明它具有依赖性 - 它需要一个实现客户端存储库接口的对象。然后它可以允许这样的对象由周围环境提供("依赖注入容器"在流行语中)。然后在测试期间,您将创建并提供(" inject")模拟实现,而不是真正的实现。

如果您必须能够在多个"真实"之间进行选择,这还有一个额外的好处。实施,您已经设置了这样做。

有很多方法可以实现这一目标。它可以像设计模式一样简单,或者对于更完整的解决方案,您可以使用依赖注入框架。

如果你绝对无法为这种做法重构你的代码,那么JavaScript足够动态,你可以拼凑一种方法拦截new的调用,从而模拟依赖注入。

答案 1 :(得分:1)

您可以将模拟实现工厂作为第二个参数传递给jest.mockas described in the docs

您可以使用它来模拟您要检查的方法。

试试这个:

jest.mock('../repositories/CompanyRepository', () => {
    findByKey: jest.fn(),
    addClient: jest.jn()
});

const mockCreate = jest.fn();

jest.mock('../repositories/CompanyRepository', () => class {
    create(...args) {
        mockCreate(...args);
    }
});

test('should be able to submit an order', async () => {
    const apiKey = 'mocked-super-key';
    const body = getMockData();

    const result = await submitOrder(body, apiKey);
    expect(result).toMatchSnapshot();
    expect(CompanyRepository.findByKey).toHaveBeenCalled();
    expect(ClientRepository.create).toHaveBeenCalled();
    expect(CompanyRepository.addClient).toHaveBeenCalled();
});

由于 CompanyRepository 是使用“new”创建的,因此我们在这种情况下使用类定义并传入一个调用“create”方法时调用的mock函数。