elasticsearch 使用NestJS/Elastic对服务进行单元测试的正确方法是什么,elasticsearch,graphql,nestjs,typegraphql,elasticsearch,Graphql,Nestjs,Typegraphql" /> elasticsearch 使用NestJS/Elastic对服务进行单元测试的正确方法是什么,elasticsearch,graphql,nestjs,typegraphql,elasticsearch,Graphql,Nestjs,Typegraphql" />

elasticsearch 使用NestJS/Elastic对服务进行单元测试的正确方法是什么

elasticsearch 使用NestJS/Elastic对服务进行单元测试的正确方法是什么,elasticsearch,graphql,nestjs,typegraphql,elasticsearch,Graphql,Nestjs,Typegraphql,我正在尝试对一个使用弹性搜索的服务进行单元测试。我想确保我使用了正确的技术 我是这个问题很多方面的新用户,所以我的大部分尝试都是从阅读其他类似的问题,并尝试在我的用例中有意义的问题。我认为createTestingModule中缺少一个字段。有时我还会看到提供者:[Service]和其他组件:[Service] const模块:TestingModule=wait Test.createTestingModule({ 提供者:[PoolJobService], }).compile() 这是我

我正在尝试对一个使用弹性搜索的服务进行单元测试。我想确保我使用了正确的技术

我是这个问题很多方面的新用户,所以我的大部分尝试都是从阅读其他类似的问题,并尝试在我的用例中有意义的问题。我认为createTestingModule中缺少一个字段。有时我还会看到
提供者:[Service]
和其他
组件:[Service]

const模块:TestingModule=wait Test.createTestingModule({
提供者:[PoolJobService],
}).compile()
这是我当前的错误:

    Nest can't resolve dependencies of the PoolJobService (?). 
    Please make sure that the argument at index [0] 
    is available in the _RootTestModule context.
这是我的代码:

    Nest can't resolve dependencies of the PoolJobService (?). 
    Please make sure that the argument at index [0] 
    is available in the _RootTestModule context.
PoolJobService

从'@nestjs/common'导入{Injectable}
从“../ElasticSearch/ElasticSearchService”导入{ElasticSearchService}
@可注射()
出口类PoolJobService{
构造函数(私有只读服务:ElasticSearchService){}
异步getPoolJobs(){
返回此.esService.getElasticSearchData('池/作业')
}
}
PoolJobService.spec.ts

从'@nestjs/testing'导入{Test,TestingModule}
从“./PoolJobService”导入{PoolJobService}
描述('PoolJobService',()=>{
let poolJobService:poolJobService
beforeach(异步()=>{
常量模块:TestingModule=等待测试。createTestingModule({
提供者:[PoolJobService],
}).compile()
poolJobService=module.get(poolJobService)
})
它('应该定义',()=>{
expect(poolJobService).tobededefined()
})
我也可以在这方面使用一些见解,但由于当前的问题,我无法正确地测试它

it('should return all PoolJobs',async()=>{
开玩笑
.spyOn(poolJobService,'getPoolJobs')
.mock实现(()=>Promise.resolve([]))
expect(wait-poolJobService.getPoolJobs()).resolves.toEqual([])
})
})

首先,您使用
提供程序的想法是正确的<代码>组件
是嵌套中不存在的
角度
特定对象。我们拥有的最接近的东西是
控制器

对于单元测试,您应该做的是测试单个函数的返回是什么,而不必深入代码库本身。在您提供的示例中,您希望使用
jest.mock
模拟您的
ElasticSearchServices
,并断言
PoolJobService
方法的返回

正如您已经指出的,Nest为我们提供了一种非常好的方法,可以通过
Test.createTestingModule
实现这一点。您的解决方案将类似于以下内容:

PoolJobService.spec.ts
从'@nestjs/testing'导入{Test,TestingModule}
从“./PoolJobService”导入{PoolJobService}
从“../ElasticSearch/ElasticSearchService”导入{ElasticSearchService}
描述('PoolJobService',()=>{
let poolJobService:poolJobService
let elasticService:ElasticSearchService//这一行是可选的,但我发现它在覆盖模拟功能时很有用
beforeach(异步()=>{
常量模块:TestingModule=等待测试。createTestingModule({
供应商:[
联合就业服务,
{
提供:ElasticSearchService,
使用价值:{
getElasticSearchData:jest.fn()
}
}
],
}).compile()
poolJobService=module.get(poolJobService)
elasticService=module.get(ElasticSearchService)
})
它('应该定义',()=>{
expect(poolJobService).tobededefined()
})
它('应该给出预期的返回',async()=>{
elasticService.getElasticSearchData=jest.fn().mockReturnValue({data:'此处的对象'})
const poolJobs=await poolJobService.getPoolJobs()
expect(poolJobs).toEqual({data:'your object here'})
})
您可以使用
jest.spy
而不是
mock
实现相同的功能,但这取决于您希望如何实现该功能

作为一条基本规则,无论构造函数中有什么,都需要对其进行模拟,只要对其进行模拟,就可以忽略被模拟对象构造函数中的任何内容。祝您测试愉快

编辑2019年6月27日

关于为什么我们要模拟
ElasticSearchService
:单元测试旨在测试特定的代码段,而不是在测试函数之外与代码进行交互。在这种情况下,我们正在测试
PoolJobService
类的函数
getPoolJobs
。这意味着我们实际上不需要全力以赴进行协作连接到数据库或外部服务器,因为这可能会使我们的测试速度变慢/在服务器停机时容易中断/修改我们不想修改的数据。相反,我们模拟外部依赖项(
ElasticSearchService
)以返回一个我们可以控制的值(理论上,这看起来与实际数据非常相似,但在这个问题的上下文中,我将其设置为字符串)。然后我们测试
getPoolJobs
返回
ElasticSearchService
getElasticSearchData
函数返回的值,因为这是该函数的功能

在这种情况下,这似乎很琐碎,可能没有什么用处,但是当外部调用之后开始有业务逻辑时,我们就清楚为什么要模拟了。假设我们在从
getPoolJobs
方法返回之前进行了某种数据转换,使字符串大写

导出类PoolJobService{
构造函数(私有只读elasticSearchService:elasticSearchService){}
getPoolJobs(数据:任意):字符串{
const returnData=this.elasticSearchService.getElasticSearchData(数据);
返回returnData.toUpperCase();
}
}
在测试中,我们可以告诉
getElasticSearchData
返回什么,并轻松断言
getPo