在 NestJS 中使用 Mongoose 测试服务
Testing Service with Mongoose in NestJS
我正在尝试在 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> {
}
}
问题是因为您将 class 传递给 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));
});
经过更多谷歌搜索后,我设法找到了这个测试示例 Repo:https://github.com/jmcdo29/testing-nestjs,其中包括 Mongo 上的示例,还建议使用 this.model(data)
会使测试复杂化,而应该使用`this.model.create(数据).
进行更改后,测试按预期进行。
我正在尝试在 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> {
}
}
问题是因为您将 class 传递给 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));
});
经过更多谷歌搜索后,我设法找到了这个测试示例 Repo:https://github.com/jmcdo29/testing-nestjs,其中包括 Mongo 上的示例,还建议使用 this.model(data)
会使测试复杂化,而应该使用`this.model.create(数据).
进行更改后,测试按预期进行。