SuperTest E2E测试GraphQL API时TypeORM实体校验器不生效
NestJS E2E测试中GraphQL接口校验失效问题
基本信息
- 技术栈:NestJS + GraphQL + TypeORM
- 问题现象:用SuperTest对GraphQL API做E2E测试时,实体字段上配置的
@IsURL()、@IsNotEmpty()等class-validator校验规则完全不触发。 - 正常场景表现:应用本地启动后,通过GraphQL Playground、curl请求访问接口时校验逻辑完全正常。
现象对比
正常运行时的接口响应
传入合法URL,接口正常返回创建成功的数据:
{ "data": { "createProject": { "uuid": "da1d8f48-2109-4629-a10f-67a5a7c3a5a2", "title": "f", "description": "descriptions", "releaseDate": null, "websiteURL": "www.f.com", "slug": "f" } } }
传入非法URL,接口正常抛出400校验错误:
{ "errors": [ { "message": "Bad Request Exception", "extensions": { "code": "BAD_USER_INPUT", "response": { "statusCode": 400, "message": [ "websiteURL must be an URL address" ], "error": "Bad Request" } } } ], "data": null }
E2E测试中的异常响应
测试用例中传入非法URL时,接口不抛错,非法数据直接落库创建成功,返回结果如下:
{ data: { createProject: { uuid: '2be26d1f-d6b9-4a82-addc-778e497cdb1e', title: 'URL Project', description: 'Sit aut iusto dolor sunt.', releaseDate: null, websiteURL: 'invalid url', slug: 'url-project' } } }
相关代码片段
测试初始化逻辑
beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [ TypeOrmModule.forRoot({ ...testDataSourceOptions, entities: [], autoLoadEntities: true, dropSchema: true, }), AppModule, ], }).compile(); const dataSource = new DataSource(testDataSourceOptions); await dataSource.initialize(); await dataSource.runMigrations(); app = moduleFixture.createNestApplication(); await app.init(); });
异常场景测试用例
it('does not allow invalid urls', () => { const newURLProject = (title: string, websiteURL: string) => { const description = faker.lorem.sentence(); const query = ` mutation CreateProject { createProject(newProject: { title: "${title}", description: "${description}", websiteURL: "${websiteURL}" }) { uuid title description releaseDate websiteURL slug } } `; return { title, description, websiteURL, query }; }; const projectURL = newURLProject("URL Project", "invalid url") console.log(projectURL.websiteURL) return request(app.getHttpServer()) .post('/graphql') .send({ query: projectURL.query }) .expect(200) .expect( ({ body: { errors: { errors } } }) => { console.log(errors) expect(errors[0].extensions.response.statusCode).toEqual(400); expect(errors[0].extensions.response.message).toEqual(["websiteURL must be an URL address"]); } ) })
说明:DTO、实体类定义本身无问题,在非测试环境下运行完全符合预期,因此不贴这部分代码。
已尝试的解决手段
- 替换请求库,改用
supertest-graphql编写测试用例,问题复现,没有解决。 - 后续考虑完全替换SuperTest框架,但改动成本较高,暂未推进。
求助
希望有遇到过同类问题的开发者提供排查方向或解决方案,感谢。
内容的提问来源于stack exchange,提问作者Bartosz Raubo
相关产品推荐
相关产品推荐

