使用 NJsonSchema 解析单元测试中的 JSON $ref



我已经将我的JSON模式分成几个文件,并根据需要以标准方式("$ref": http://rootpath/otherfile.json#/definitions/link(引用它们。

JSON 文件是项目中的嵌入资源。rootpath根据部署位置而变化。但是在生产中一切正常(发出请求时,JSON 响应将按模式获得,当根据架构 NJsonSchema 验证响应时,内部获取参考架构并提取完成验证所需的内容(

然而,当涉及到测试时,这是另一回事。响应正常,获取第一个架构已存根。rootpath是,一切都是相对于http://testapi/的,但这实际上并不存在。因此,当 NJsonSchema 尝试获取引用模式时,它会查找类似http://testapi/otherfile.json#/definitions/link的内容,这显然失败了。

通过阅读本文,我想我想使用重载来获取允许我指定 JsonReferenceResolver 的JsonSchema4对象,然后我可以在生产中使用默认值并注入我自己的一个进行测试,以便它在我控制并存在的地方查找$ref。但我看不到任何文档或示例。

示例架构:

{ // root.json
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "@Model.Root/schemas/root.json",
"title": "Root",
"properties": {
"link": { "$ref": "@Model.Root/schemas/common.json#/definitions/link" }             
},
"required": [ "link" ]
}
{ // common.json - different file to the above
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "@Model.Root/schemas/common.json",
"definitions": {
"link": {
"title": "Link",
"type": "object",
"properties": {
"rel": { "type": "string" },
"href": { "type": "string" }
},
"required": [ "rel", "href" ]
}
}
}

示例响应:

{
"schema": "http://testapi/schemas/root.json",
"link": { "rel": "self", "href": "http://testapi/root" }
};

验证代码 (C#(:

using NJsonSchema;
using NJsonSchema.Validation;
...
JsonSchema4 schema = await JsonSchema4.FromJsonAsync(<contents of root.json file>);
string response = "{ ""link"": { ""rel"": ""self"", ""href"": ""http://testapi/root"" } }";
ICollection<ValidationError> errors = schema.Validate(response);
...

我指定 JsonReferenceResolver 的预感是在正确的行上。在上面的例子中,我无法从root.json获得对common.json的引用,以便在测试环境中"工作",因为在那个环境中服务/路径不存在。

因此,在设置环境时,我确实知道common.json是什么,即我知道它的内容是字符串,因此可以将其作为模式(JsonSchema4 commonSchema = JsonSchema4.FromJsonAsync(commonJsonAsString).Result;(。

使用它,我可以设置一个"引用解析器工厂",并在其中添加一个文档引用,以便从我的commonSchema获得对http://testapi/schemas/common.json#/...的所有引用,即

private Func<JsonSchema4, JsonReferenceResolver> referenceResolverFactory;
this.referenceResolverFactory = x =>
{
JsonSchemaResolver schemaResolver = new JsonSchemaResolver(x, new JsonSchemaGeneratorSettings());
JsonReferenceResolver referenceResolver = new JsonReferenceResolver(schemaResolver);
referenceResolver.AddDocumentReference("http://testapi/schemas/common.json", commonSchema);
return referenceResolver;
};

可以通过以相同的方式添加更多文档引用来解析不同的引用。

然后,当我尝试转换 root.json 模式(引用 common.json(或另一个模式(引用 common.json(时,我使用了传入referenceResolverFactory的重载FromJsonAsync

private bool GetAndValidateResponse(string schemaName, string response, string schemaAsString)
{
// schemaName:     Name of the schema being validated, e.g. "root.json"
// response:       http response body as a string, see 'Example response' in question
// schemaAsString: The schema being validate as a string, e.g. root.json contents in question
//
// Check the response object against the schema
JsonSchema4 schema = JsonSchema4.FromJsonAsync(schemaAsString, schemaName, this.referenceResolverFactory).Result;
ICollection<ValidationError> errors = schema.Validate(response);
return errors.Count < 1;
}

就我而言,对于单元测试,我只对它是否有效感兴趣,因此布尔返回值。如果您对确切的错误感兴趣,显然您可以返回集合。

此外,我只为每个单元测试类设置工厂一次,而不是每个测试。但是,对于架构中的每个ref,它正确地进入工厂。

相关内容

  • 没有找到相关文章

最新更新