检查是否在unit testing中调用函数

您好我试图写一些unit testingJest为我编写的模块,但目前卡住,需要一些build议如何继续。

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 } 

我可以轻松地testing每个函数( getCompanyByKeycreateClientaddClientToCompany )通过传递一个嘲弄的存储库。

但是我也想通过检查我的仓库函数是否被调用来testing我的submitOrder函数的“stream”。 但是,我会需要每个存储库的实例,我没有实例化,直到我的submitOrder函数。

像这样的东西,这与我如何testing我的function是类似的。

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

你有任何提示,我可以testing,如果我的知识库被称为?

你所描述的问题是dependency injection背后的激励因素之一。

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

这还有一个额外的好处,就是如果你必须能够在多个“真实”的实现中进行select,那么你已经设置了这个function。

有很多方法可以做到这一点。 它可以像devise模式一样简单,或者可以使用dependency injection框架的更完整的解决scheme。

如果你绝对不能重构你的代码,那么JavaScript是足够dynamic的,你可以拼凑一个方法来拦截new的调用,从而模拟dependency injection。

您可以将模拟实现工厂作为第二个parameter passing给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”创build的,因此我们在这种情况下使用类定义,并在调用“create”方法时传入一个模拟函数。