我尝试使用已实现的Jest框架在NestJS中测试我的应用程序的控制器。问题是我的应用程序与MongoDB和CacheService有依赖关系,它们包含在Nest中,但仍需要实现。
这是我想要测试的控制器:
计算器.控制器.ts
@Controller('/calculator')
export class CalculatorController {
constructor(
@Inject(HISTORY_SERVICE)
private historyService: HistoryService,
@Inject(CACHE_SERVICE)
private readonly cacheService: CacheService,
) {}
@Get()
getResult(
@Query() expressionDto: ExpressionDto,
): Promise<CalculationResultDto> {
const { expression } = expressionDto;
const response = this.cacheService
.checkInCache(expression)
.then((result) => {
const dto = { result: `${result}`, expression };
const historyItem = this.historyService.create(dto);
return historyItem;
});
return response;
}
}
如您所见,我没有在此控制器中使用CalculatorService,因为计算器的算法如下:CalculatorController以表达式的形式获取请求以进行计数。表达式被传递给CacheService。在缓存中检查表达式,如果不存在,则从CacheService调用CalculatorService,并将结果返回给CalculatorController。接下来,调用HistoryService,它负责将计算结果存储在数据库中。2这对于将表达式的计算结果以正确的形式发送给用户是必要的。3数据库添加一个ID等等。
在所有操作结束时,将结果发送到客户端。
现在我们来看看测试。
计算器.控制器.规格ts
jest.mock('../calculator.service.ts');
let calculatorController: CalculatorController;
let calculatorService: CalculatorService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [HistoryModule],
controllers: [CalculatorController],
providers: [
{ useClass: CalculatorService, provide: CALCULATOR_SERVICE },
{
useClass: ExpressionCounterService,
provide: EXPRESSION_COUNTER_SERVICE,
},
{
useClass: RegExCreatorService,
provide: REGEXP_CREATOR_SERVICE_INTERFACE,
},
{ useClass: CacheService, provide: CACHE_SERVICE },
{ useClass: HistoryService, provide: HISTORY_SERVICE },
],
}).compile();
calculatorController =
moduleRef.get<CalculatorController>(CalculatorController);
calculatorService = moduleRef.get<CalculatorService>(CalculatorService);
jest.clearAllMocks();
});
describe('getResult', () => {
describe('when getResult is called', () => {
beforeEach(async () => {
await calculatorController.getResult(calculatorStub().request);
});
test('then it should call calculatorService', () => {
expect(calculatorService.getResult).toBeCalledWith(
calculatorStub().request.expression,
);
});
});
});
错误为
Nest can't resolve dependencies of the CacheService (?, CALCULATOR_SERVICE). Please make sure that the argument CACHE_MANAGER at index [0] is available in the RootTestModule context.
我完全模仿了真实的的计算器模块,但即使这样它也不工作。这里是我的计算器模块作为一个例子。
计算器模块ts
@Module({
imports: [HistoryModule],
controllers: [CalculatorController],
providers: [
{ useClass: CalculatorService, provide: CALCULATOR_SERVICE },
{ useClass: ExpressionCounterService, provide: EXPRESSION_COUNTER_SERVICE },
{
useClass: RegExCreatorService,
provide: REGEXP_CREATOR_SERVICE_INTERFACE,
},
{ useClass: CacheService, provide: CACHE_SERVICE },
{ useClass: HistoryService, provide: HISTORY_SERVICE },
],
})
export class CalculatorModule {}
如果你们中有人能帮我解决这个问题,我将非常感激。以防万一,我会留下一个项目库的链接。
https://github.com/tresor13/calculator/tree/main/server/src
1条答案
按热度按时间vybvopom1#
很可能你没有模仿
CacheService
,而是使用了真实的的类。在这种情况下,Nest尝试从类创建示例,但它有一些依赖项,这些依赖项没有在提供者列表中提供。因此,您需要在提供者列表中添加
CacheService
的依赖项,或者模拟该类。或
mockCacheService
只是一个简单的对象,它的每个方法都被jest.fn()
模拟:useValue语法对于注入常量值、将外部库放入Nest容器或用mock对象替换真实的实现非常有用,假设您希望强制Nest使用模拟CatsService进行测试。