У меня есть полезная нагрузка 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;
}
Затем я украсил класс Destination атрибутом [JsonConverter]
, приняв typeof(DestinationConverter)
.
Это работает правильно, когда я использую 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