Ste*_*ock 3 testing unit-testing node.js nestjs sequelize-typescript
控制器及测试方法:
import { Controller, Get, Response, HttpStatus, Param, Body, Post, Request, Patch, Delete, Res } from '@nestjs/common';
@Controller('api/parts')
export class PartController {
constructor(private readonly partsService: partsService) { }
@Get()
public async getParts(@Response() res: any) {
const parts = await this.partsService.findAll();
return res.status(HttpStatus.OK).json(parts);
}
}
Run Code Online (Sandbox Code Playgroud)
这是必须测试 getParts 方法的单元测试:
describe('PartsController', () => {
let partsController: PartsController;
let partsService: partsService;
beforeEach(async () => {
partsService = new partsService(Part);
partsController= new PartsController(partsService);
});
describe('findAll', () => {
it('should return an array of parts', async () => {
const result = [{ name: 'TestPart' }] as Part[];
jest.spyOn(partsService, 'findAll').mockImplementation(async () => result);
const response = {
json: (body?: any) => {
expect(body).toBe(result);
},
status: (code: number) => response,
};
await partsController.getParts(response);
});
});
});
Run Code Online (Sandbox Code Playgroud)
这个测试工作正常,但我认为这是一个糟糕的解决方案。当我调查这个问题时,我看到了这个选项:
const response = {
json: (body?: any) => {},
status: (code: number) => response,
};
expect(await partsController.getParts(response)).toBe(result);
Run Code Online (Sandbox Code Playgroud)
但是当我尝试它时,我的测试不起作用,导致 await partsController.getParts(response) // undefined 那么我应该怎么做才能使我的测试看起来不错?
在我使用的解决方案中:nodeJS sequelize、nestJS、typescript
好的,所以我猜您的问题在于您实例化和使用控制器和服务的方式。
让NestJs 测试工具为您完成这项工作,如下所示:
describe('Parts Controller', () => {
let partsController: PartsController;
let partsService: PartsService;
beforeEach(async () => {
// magic happens with the following line
const module = await Test.createTestingModule({
controllers: [
PartsController
],
providers: [
PartsService
//... any other needed import goes here
]
}).compile();
partsService = module.get<PartsService>(PartsService);
partsController = module.get<PartsController>(PartsController);
});
// The next 4 lines are optional and depends on whether you would need to perform these cleanings of the mocks or not after each tests within this describe section
afterEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});
it('should be defined', () => {
expect(partsController).toBeDefined();
expect(partsService).toBeDefined();
});
describe('findAll', () => {
it('should return an array of parts', async () => {
const result: Part[] = [{ name: 'TestPart' }];
jest.spyOn(partsService, 'findAll').mockImplementation(async (): Promise<Part[]> => Promise.resolve(result));
const response = {
json: (body?: any) => {},
status: (code: number) => HttpStatus.OK,
};
expect(await partsController.getParts(response)).toBe(result);
});
});
});
Run Code Online (Sandbox Code Playgroud)
我自己还没有测试过代码,所以试一试(不太确定部件控制器中响应类型的响应模拟)。
顺便说一下,关于零件控制器,您应该利用 express 的 Response 类型 - 尝试按如下方式重写代码:
import { Controller, Get, Response, HttpStatus, Param, Body, Post, Request, Patch, Delete, Res } from '@nestjs/common';
import { Response } from 'express';
@Controller('api/parts')
export class PartController {
constructor(private readonly partsService: partsService) { }
@Get()
public async getParts(@Response() res: Response) { // <= see Response type from express being used here
const parts = await this.partsService.findAll();
return res.status(HttpStatus.OK).json(parts);
}
}
Run Code Online (Sandbox Code Playgroud)
最后看看 nest 官方文档的这一部分,也许它可以让您对您要实现的目标有所了解:
- Nest 测试部分
- Nest 库方法
在第二个链接中,几乎在页面的开头,在https://docs.nestjs.com/controllers#request-object部分中声明如下:
- 为了与跨底层 HTTP 平台(例如 Express 和 Fastify)的类型兼容,Nest 提供了 @Res() 和 @Response() 装饰器。@Res() 只是@Response() 的别名。两者都直接暴露底层原生平台响应对象接口。使用它们时,您还应该导入底层库的类型(例如,@types/express)以充分利用它们。请注意,当您在方法处理程序中注入 @Res() 或 @Response() 时,您会将 Nest 置于该处理程序的特定于库的模式中,并且您将负责管理响应。这样做时,您必须通过调用响应对象(例如 res.json(...) 或 res.send(...))来发出某种响应,否则 HTTP 服务器将挂起。
希望它有所帮助,如果它有助于找到另一个解决方案,请不要犹豫发表评论或分享您的解决方案!:)
顺便欢迎来到 StackOverflow 平台!