Spring Boot GraphQL单元测试中自定义Date标量未被识别问题排查
解决GraphQL单元测试中的NonExecutableDefinition错误
这个错误的核心原因是:你在单元测试中通过documentSource加载了完整的GraphQL Schema文件(包含scalar Date、类型定义等),但GraphQL测试执行器期望的是可执行的操作语句(比如query或mutation),而非Schema的类型定义部分,所以验证器会抛出NonExecutableDefinition错误,认为Date标量定义是不可执行的内容。
具体解决方案
1. 拆分GraphQL文件
把你的GraphQL文件拆成两部分:
- 主Schema文件:存放所有类型、标量、查询/突变的定义(比如
schema.graphqls),放在classpath下,@GraphQlTest会自动扫描加载它。 - 测试查询文件:只存放当前测试需要执行的查询语句(比如
findMyObjectQuery.graphql),内容如下:
query findMyObject($myVar: Int) { findMyObject(myVar: $myVar) { ATTR1 ATTR2 } }
2. 简化测试代码
移除手动创建documentSource的逻辑,因为@GraphQlTest已经会自动加载你的Schema,直接使用测试查询文件即可:
@GraphQlTest(MyController.class) @Import(DateScalarConfiguration.class) // 其他必要的注解 class MyControllerTest { @Autowired private GraphQlTester graphQlTester; @Test public void findMyObjectTest() { this.graphQlTester .documentName("findMyObjectQuery") // 指向测试查询文件 .variable("myVar", 618) .execute() .path("findMyObject") .matchesJson("{\"data\":{\"findMyObject\":{\"ATTR1\":618,\"ATTR2\":\"1999-12-31\"}}}"); } }
3. 额外检查点
- 确保你的
DateScalarConfiguration中定义的标量名称"Date"和Schema里的scalar Date完全一致。 - 如果你不想拆分文件,也可以直接在测试中内联查询语句,比如用
.document("query findMyObject($myVar: Int) { ... }")代替documentName。
为什么之前的代码会出错?
当你手动通过ResourceDocumentSource加载完整Schema时,测试执行器会把Schema里的类型定义(比如scalar Date、type MyObject)当成查询的一部分,但这些是Schema定义内容,不是可以直接执行的查询操作,因此GraphQL的验证器会判定它们为"非可执行定义",从而抛出错误。
内容的提问来源于stack exchange,提问作者mtnp
相关产品推荐
相关产品推荐

