gpt4 book ai didi

C# 单元测试 Newtonsoft JSON 模型

转载 作者:行者123 更新时间:2023-11-28 21:07:33 25 4
gpt4 key购买 nike

我从单元测试开始,并使用 XUnit 进行测试。

我有一个模型:

using Newtonsoft.Json;
namespace HomeAddressSearch
{
public class Properties
{
[Required]
[JsonProperty(PropertyName = "civic_number")]
public string CivicNumber { get; set; }

[JsonProperty(PropertyName = "address")]
public string Address { get; set; }

[JsonProperty(PropertyName = "postal_code")]
public string PostalCode { get; set; }

[JsonProperty(PropertyName = "city_name")]
public string CityName { get; set; }
}
}

我有一个 JSON,我从中获取如下值:

[
{
"properties": {
"civic_number": "100",
"address": "100, king street",
"postal_code": "H0H0H0",
"city_name": "Windsor"
},
"owner": {
"name": "John Doe",
"age": "40"
},
}
]

所以我想测试那个模型,为此我想到了:

  • 由于 CivicNumber 是必需的,我想确保 JSON 中没有空值或空字符串,因此具有空值的测试会使测试崩溃
  • 如果有人更改 JSON 并删除属性对象中的字段之一,例如 city_name,那么测试就会失败,所以我知道我要么需要调整我的模型,要么返回到原始 JSON 格式
  • 检查 JSON 值的格式,在本例中都是字符串,可以注入(inject)到我的模型中
  • 从模型中只有 3 个条目的较短版本的 JSON 文件运行注入(inject),以确保一切正常

我是否在正确的道路上以及如何做到这一点,这将极大地帮助和启动我做很多其他事情。

谢谢!

最佳答案

这不是您需要进行单元测试的东西,而是利用 Newtonsoft 的 JSON 验证。

// Generate a JSON schema from your object.
var schemaGenerator = new JSchemaGenerator();
var schema = schemaGenerator.Generate(typeof(HomeAddressSearch.Properties));

// Parse the JSON passed in, then validate it against the schema before proceeding.
List<ValidationErrors> validationErrors;
JObject addressToValidate = JObject.Parse(jsonStringToValidate);
bool isValid = addressToValidate.IsValid(schema, out validationErrors);

如果您想详细说明对调用者的响应,您可以从那里遍历验证错误。

单元测试适用于断言静态代码行为,因此如果您的 JSON 模式指定规则,则单元测试所做的断言是:

  • 断言您的代码验证了 JSON 架构,如果无效则拒绝它。
  • 您的代码应对有效的 JSON 数据场景执行的任何行为。

** 编辑 ** 详细说明使用验证,然后执行验证的单元测试:

假设我们有一个 API 接受 JSON 数据作为字符串而不是类:(我们应该能够使用 model.IsValid())

public class AddressController : ApiController
{
private readonly IJsonEntityValidator<HomeAddressSearch.Properties> _validator = null;

public AddressController(IJsonEntityValidator validator)
{
_validator = validator;
}
public ActionResult Search(string jsonModel)
{
if(string.IsNullOrEmpty(jsonModel))
// handle response for missing model.

var result = _validator.Validate<HomeAddressSearch.Properties>(jsonModel);
if (!result.IsValid)
// handle validation failure for the model.
}
}

public class JSonEntityValidator<T> : IJsonEntityValidator<T> where T: class
{
IJsonEntityValidator<T>.Validate(string jsonModel)
{
// Generate a JSON schema from your object.
var schemaGenerator = new JSchemaGenerator();
var schema = schemaGenerator.Generate(typeof(T));

// Parse the JSON passed in, then validate it against the schema before proceeding.
List<ValidationErrors> validationErrors;
JObject model = JObject.Parse(jsonModel);
bool isValid = model.IsValid(schema, out validationErrors);
return new JsonValidateResult
{
IsValid = isValid,
ValidationErrors = validationErrors
};
}
}

单元测试将针对 Controller ,断言它使用验证器来确保 JSON 数据有效:

[Test]
public void EnsureHomeAddressSearchValidatesProvidedJson_InvalidJSONScenario()
{
string testJson = buildInvalidJson(); // the value here doesn't matter beyond being recognized by our mock as being passed to the validation.
var mockValidator = new Mock<IJsonEntityValidator<HomeAddressSearch.Properties>>();
mockValidator.Setup(x => x.Validate(testJson)
.Returns(new JsonValidationResult { IsValid = false, ValidationErrors = new ValidationError[] { /* populate a set of validation errors. */ }.ToList()});
var testController = new AddressController(mockValidator.Object);
var result = testController.Search(testJson);
// Can assess the result from the controller based on the scenario validation errors returned....

// Validate that our controller called the validator.
mockValidator.Verify(x => x.Validate(testJson), Times.Once);
}

此测试完成的是断言我们的 Controller 将调用验证逻辑来​​评估我们提供的 JSON。如果有人修改 Controller 并删除对 Validate 的调用,测试将失败。

您不需要为这样的测试编写 JSON 对象,“fred”就可以了,因为它只是供模拟识别的占位符。此场景中的模拟配置为:“我希望以特定的值(value)被调用。[fred]”“当我得到那个值时,我会说它无效,并且我会包含一组特定的验证错误。”从那里您可以断言 Controller 的结果响应以查看它是否反射(reflect)了验证错误。我们还要求最后的 Mock 验证它是用特定值调用的。

现在,如果您还想强制/断言对架构的更改,那么您可以针对验证器本身编写测试。例如检测有人删除或更改模型上的属性。

[Test]
EnsureHomeAddressValidatorExpectsCivicNumberIsRequired()
{
var testJson = generateJsonMissingCivicNumber();
IJsonEntityValidator<HomeAddressSearch.Properties> testValidator = new JsonEntityValidator<HomeAddressSearch.Properties>();
var result = testValidator.Validate(testJson);
Assert.IsFalse(result.IsValid);
// Assert result.ValidationErrors....
}

关于C# 单元测试 Newtonsoft JSON 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52415325/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com