【发布时间】:2020-10-22 19:31:36
【问题描述】:
我有一个 json 有效负载,我想以一种重要的方式反序列化。
{
"destinationId": 123
}
目标类是
public class SomeObject
{
public Destination Destination { get; set; }
}
public class Destination
{
public Destination(int destinationId)
{
Id = destinationId;
}
public int Id { get; set; }
}
为了能够做到这一点,我创建了一个 JsonConverter 来处理它。
这里是 ReadJson 方法:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (CanConvert(objectType))
{
var value = reader.Value;
if (value is long v)
{
// TODO: this might overflow
return new Destination((int)v);
}
}
return null;
}
然后我用一个接受typeof(DestinationConverter) 的[JsonConverter] 属性装饰了Destination 类。
当我使用 JsonConvert.DeserializeObject<SomeObject>(myString)(参见下面的单元测试)时,这可以正常工作,但我在为 JsonConverter 创建成功的单元测试时遇到问题(参见下面的第二个测试)。
[Test, AutoData]
public void SomeObject_is_correctly_deserialized(SomeObject testObject)
{
var json = $@"{{""destinationId"":{testObject.Destination.Id}}}";
Console.WriteLine($"json: {json}");
var obj = JsonConvert.DeserializeObject<SomeObject>(json);
Assert.That(obj.Destination.Id, Is.EqualTo(testObject.Destination.Id));
}
[Test, AutoData]
public void ReadJson_can_deserialize_an_integer_as_Destination(DestinationConverter sut, int testValue)
{
JsonReader reader = new JTokenReader(JToken.Parse($"{testValue}"));
var obj = sut.ReadJson(reader, typeof(Destination), null, JsonSerializer.CreateDefault());
var result = obj as Destination;
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.InstanceOf<Destination>());
Assert.That(result.Id, Is.EqualTo(testValue));
}
我一直在寻找一种方法来正确地对转换后的转换进行单元测试,但我只找到了使用整个 DeserializeObject 而不仅仅是测试转换器的示例。
PS:我在 .NET Fiddle 中粘贴了所有必要的代码:https://dotnetfiddle.net/oUXi6k
【问题讨论】:
-
你为什么把
CanConvert(objectType)放在ReadJson()中?ReadJson()只有在已知转换器适用时才应该被调用。 -
在以前的版本中,我遇到了在 SomeObject 类的第二个属性上调用该方法的问题(该类已编辑)。无论如何,删除它并不能解决问题。
-
看来您需要提供 JsonReader 的实现。
-
ReadJson()是反序列化的实现细节,你真的需要对那个方法进行单元测试吗?在反序列化期间无论如何都会调用它。 -
@dbc 的回答清楚地表明我需要它。此外,对组件进行单元测试就是要测试使用它的组件的实现细节。
标签: c# .net unit-testing json.net nunit