Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 检查单元测试中是否调用了函数_Javascript_Node.js_Unit Testing_Jestjs - Fatal编程技术网

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

Javascript 检查单元测试中是否调用了函数,javascript,node.js,unit-testing,jestjs,Javascript,Node.js,Unit Testing,Jestjs,您好,我正试图为我编写的模块编写一些单元测试,但目前有点卡住了,需要一些关于如何继续的建议 export const submitOrder = async (body, key) => { const clientRepo = new ClientRepository(db) const companyRepo = new CompanyRepository(db) const company = await getCompanyByKey( companyRepo

您好,我正试图为我编写的模块编写一些单元测试,但目前有点卡住了,需要一些关于如何继续的建议

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
}
通过传递模拟存储库,我可以轻松测试每个函数(
getCompanyByKey
createClient
&
addClientToCompany

但我还想通过检查是否调用了我的存储库函数来测试我的
submitor
函数的“流程”。但是我需要每个存储库的实例,在我的
submitor
函数之前我不会实例化它

类似于这样,这与我单元测试函数的方式类似

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

关于如何测试是否调用了我的存储库,您有什么建议吗?

您描述的问题是依赖注入背后的一个动机因素

举个例子:您的
submitor()
代码使用
new
直接实例化特定实现的客户机存储库
ClientRepository
。相反,它可以声明它有一个依赖项——它需要一个实现客户机存储库接口的对象。然后,它可以允许由周围环境(buzzword ese中的“依赖注入容器”)提供这样的对象。然后在测试期间,您将创建并提供(“注入”)一个模拟实现,而不是真正的实现

这还有一个额外的好处,即如果您必须能够在多个“真实”实现之间进行选择,那么您也已经做好了这样做的准备

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


如果您绝对不能为这种做法重构代码,那么JavaScript是动态的,您可能可以拼凑出一种方法来拦截
new
的调用,从而模拟依赖项注入。

您可以将模拟实现工厂作为第二个参数传递给
jest.mock

您可以使用它来模拟要检查是否已调用的方法

试试这个:

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”方法时被调用。

是的,我想我理解您的意思。类似于:
container.register('companyRepository',newcompanyrepository())
?但是如果我在我的测试套件中执行相同的操作,但是
container.register('companyRepository',new MockCompanyRepository())
,它不会覆盖我的mock吗?我想我们在
container.register('companyRepository',new companyRepository())
的位置上做出了相互矛盾的假设。这是一个在测试期间永远不会执行的行。对,所以我需要一些配置文件来指出函数需要哪些依赖项以及在哪个环境中(生产和测试)?诸如此类。解决将依赖关系映射到具体实现/实例的问题是一个成熟的依赖关系注入框架工作的一大部分。通常情况下,您会在生产环境中运行某种初始化阶段,以设置“真实”实例以注入所有依赖关系,但您不会在单元测试中运行该阶段。相反,每个测试用例都为测试中的代码设置依赖项。不幸的是,这不起作用,因为my
CompanyRepository
是用new关键字实例化的。尽管我可以在
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是我仍然不能测试我的存储库函数。好的,你也可以让模拟工厂返回一个类。我已经更新了我的代码示例,请尝试一下