【问题标题】:Testing Service with Mongoose in NestJS在 NestJS 中使用 Mongoose 测试服务
【发布时间】:2020-11-20 04:56:57
【问题描述】:

我正在尝试在 NestJS 中测试我的 LoggingService,虽然我看不到测试有任何问题,但我得到的错误是 Error: Cannot spy the save property because it is not a function; undefined given instead

正在测试的函数(为简洁起见):

@Injectable()
export class LoggingService {
  constructor(
    @InjectModel(LOGGING_AUTH_MODEL) private readonly loggingAuthModel: Model<IOpenApiAuthLogDocument>,
    @InjectModel(LOGGING_EVENT_MODEL) private readonly loggingEventModel: Model<IOpenApiEventLogDocument>,
  ) {
  }
  
  async authLogging(req: Request, requestId: unknown, apiKey: string, statusCode: number, internalMsg: string) {
    
    const authLog: IOpenApiAuthLog = {
///
    }
    
    await new this.loggingAuthModel(authLog).save();
  }
}

这几乎是我的第一个 NestJS 测试,我可以说这是测试它的正确方法,考虑到错误在最后似乎是正确的。

describe('LoggingService', () => {
  let service: LoggingService;
  let mockLoggingAuthModel: IOpenApiAuthLogDocument;
  let request;
  
  beforeEach(async () => {
    request = new JestRequest();
    
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        LoggingService,
        {
          provide: getModelToken(LOGGING_AUTH_MODEL),
          useValue: MockLoggingAuthModel,
        },
        {
          provide: getModelToken(LOGGING_EVENT_MODEL),
          useValue: MockLoggingEventModel,
        },
      ],
    }).compile();
    
    service = module.get(LoggingService);
    mockLoggingAuthModel = module.get(getModelToken(LOGGING_AUTH_MODEL));
  });
  
  it('should be defined', () => {
    expect(service).toBeDefined();
  });
  
  it('authLogging', async () => {
    const reqId = 'mock-request-id';
    const mockApiKey = 'mock-api-key';
    const mockStatusCode = 200;
    const mockInternalMessage = 'mock-message';
    
    await service.authLogging(request, reqId, mockApiKey, mockStatusCode, mockInternalMessage);
    
    const authSpy = jest.spyOn(mockLoggingAuthModel, 'save');
    expect(authSpy).toBeCalled();
  });
});

模拟模型:

class MockLoggingAuthModel {
  constructor() {
  }
  
  public async save(): Promise<void> {
  }
}

【问题讨论】:

    标签: javascript unit-testing nestjs nestjs-testing


    【解决方案1】:

    问题在于您将一个类传递给TestingModule,同时告诉它它是一个值。

    使用useClass 创建TestingModule

    beforeEach(async () => {
      request = new JestRequest();
      
      const module: TestingModule = await Test.createTestingModule({
        providers: [
          LoggingService,
          {
            provide: getModelToken(LOGGING_AUTH_MODEL),
            // Use useClass
            useClass: mockLoggingAuthModel,
          },
          {
            provide: getModelToken(LOGGING_EVENT_MODEL),
            // Use useClass
            useClass: MockLoggingEventModel,
          },
        ],
      }).compile();
      
      service = module.get(LoggingService);
      mockLoggingAuthModel = module.get(getModelToken(LOGGING_AUTH_MODEL));
    });
    

    【讨论】:

    • 这给了我一个新的错误:TypeError: this.loggingAuthModel is not a constructor
    • 用服务文件中的其余内容更新了 OP,仅此而已。谢谢
    • 感谢@Baboo_ 的帮助,但在找到github.com/jmcdo29/testing-nestjs/tree/master/apps/mongo-sample 之后,我最终只是更改了代码,该示例还建议避免做我所做的事情,因为它会使测试变得非常复杂。
    【解决方案2】:

    经过更多谷歌搜索后,我设法找到了这个测试示例 Repo:https://github.com/jmcdo29/testing-nestjs,其中包括 Mongo 上的示例,还建议使用 this.model(data) 使测试复杂化,应该使用 `this.model.create(data)。

    进行更改后,测试按预期工作。

    【讨论】:

      猜你喜欢
      • 2019-11-22
      • 2020-07-16
      • 2019-08-29
      • 2020-02-04
      • 2019-07-16
      • 2019-12-22
      • 2020-09-01
      • 2020-07-16
      • 2020-03-22
      相关资源
      最近更新 更多