如何在NestJS中模拟提供者的记录器依赖关系



首先,我不确定这是否是一件事,这是我第一次为NestJs编写单元测试。

我正试图为一个控制器写一些单元测试,它的构造函数中有以下依赖项:

@Controller('builder/instance')
export class InstanceController {
private executor: Executor;
constructor(
@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
private stripeService: StripeService,
private instanceService: InstanceService,
private organizationService: OrganizationService,
private executorFactory: ExecutorFactory,
private socketService: SocketService,
private auditLogService: AuditLogService,
) {
this.executor = this.executorFactory.getExecutor();
}

这是我的测试套件的开始:

describe('InstanceController', () => {
let controller: InstanceController;
const mockStripeService = {};
const mockInstanceService = {};
const mockOrganizationService = {};
const mockExecutorFactory = {};
const mockSocketService = {};
const mockAuditLogService = {};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
// imports: [AccountModule],
controllers: [InstanceController],
providers: [
StripeService,
InstanceService,
OrganizationService,
ExecutorFactory,
SocketService,
AuditLogService,
],
})
.overrideProvider(StripeService)
.useValue(mockStripeService)
.overrideProvider(InstanceService)
.useValue(mockInstanceService)
.overrideProvider(OrganizationService)
.useValue(mockOrganizationService)
.overrideProvider(ExecutorFactory)
.useValue(mockExecutorFactory)
.overrideProvider(SocketService)
.useValue(mockSocketService)
.overrideProvider(AuditLogService)
.useValue(mockAuditLogService)
.compile();
});
it('should be defined', () => {
expect(controller).toBeDefined();
});

以下堆栈跟踪失败:

Cannot find module 'src/winston/winston.constants' from 'account/user/user.service.ts'
Require stack:
account/user/user.service.ts
sockets/socket.service.ts
builder/instance/instance.controller.spec.ts
5 | import * as argon2 from 'argon2';
6 | import { JwtService } from '@nestjs/jwt';
>  7 | import { WINSTON_MODULE_PROVIDER } from 'src/winston/winston.constants';
| ^
8 | import { Organization } from '../organization/organization.entity';
9 | import { User } from './user.entity';
10 | import { ConfigService } from '../../config/config.service';
at Resolver.resolveModule (../node_modules/jest-resolve/build/resolver.js:324:11)
at Object.<anonymous> (account/user/user.service.ts:7:1)

从日志中,我假设问题来自提供者SocketService,它又有一个提供者UserService,它反过来又注入了Winston Logger,如下所示:

@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger

我试图将UserService添加到我的测试套件中的providers数组中,并添加一个空对象的模拟实现,但这并没有解决问题。不确定从这里还可以尝试什么,我是必须在mockSocketService中添加一个mock提供程序,还是必须添加一个模拟记录器?

任何帮助都将不胜感激,如果我能提供更多代码以便于理解,请告诉我。

更新

将路径更改为relative解决了模拟服务中Winston依赖关系的问题,但现在Jest抱怨无法解决控制器中的Winston依赖性。这是因为它是从另一个模块导出的,但通过阅读它,我了解到将整个模块导入单元测试是一种糟糕的做法。我试着这样嘲笑Logger:

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
// imports: [AccountModule],
controllers: [InstanceController],
providers: [
Logger,
],
})
.overrideProvider(Logger)
.useValue(mockLogger)
.compile();
});

但运气不好,我也试着这样嘲笑温斯顿,结果也是负面的。

已解决

我终于能够想出如何嘲笑注入的温斯顿记录器了。这是完整的代码:

describe('InstanceController', () => {
let controller: InstanceController;
const mockStripeService = {};
const mockInstanceService = {};
const mockOrganizationService = {};
const mockExecutorFactory = {};
const mockSocketService = {};
const mockAuditLogService = {};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
// imports: [AccountModule],
controllers: [InstanceController],
providers: [
{ provide: WINSTON_MODULE_PROVIDER, useValue: {} },
StripeService,
InstanceService,
OrganizationService,
ExecutorFactory,
SocketService,
AuditLogService,
],
})
.overrideProvider(StripeService)
.useValue(mockStripeService)
.overrideProvider(InstanceService)
.useValue(mockInstanceService)
.overrideProvider(OrganizationService)
.useValue(mockOrganizationService)
.overrideProvider(ExecutorFactory)
.useValue(mockExecutorFactory)
.overrideProvider(SocketService)
.useValue(mockSocketService)
.overrideProvider(AuditLogService)
.useValue(mockAuditLogService)
.compile();
controller = module.get<InstanceController>(InstanceController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

最新更新