Кто-нибудь создал инструмент тестирования DataContract?

Кто-нибудь видел библиотеку, которая тестирует WCF DataContracts? Мотивация по поводу этого вопроса заключается в том, что я просто нашел ошибку в своем приложении, которая возникла из-за того, что я не аннотировал свойство с атрибутом DataMember - в результате это свойство не сериализовалось.

Я имею в виду API, который, учитывая определенный тип DataContract, автоматически заполняет его элементы случайными данными, включая любой дочерний DataContracts, а затем сериализует его через один из WCF Serializers/Formatters, а затем проверяет, что все данных были перенесены.

Кто-нибудь?

Ответ 1

Достаточно просто использовать DataContractSerializer для сериализации вашего объекта в MemoryStream, а затем десериализовать его в качестве нового экземпляра.

Здесь класс, демонстрирующий эту сериализацию в оба конца:

public static class WcfTestHelper
{
    /// <summary>
    /// Uses a <see cref="DataContractSerializer"/> to serialise the object into
    /// memory, then deserialise it again and return the result.  This is useful
    /// in tests to validate that your object is serialisable, and that it
    /// serialises correctly.
    /// </summary>
    public static T DataContractSerializationRoundTrip<T>(T obj)
    {
        return DataContractSerializationRoundTrip(obj, null);
    }

    /// <summary>
    /// Uses a <see cref="DataContractSerializer"/> to serialise the object into
    /// memory, then deserialise it again and return the result.  This is useful
    /// in tests to validate that your object is serialisable, and that it
    /// serialises correctly.
    /// </summary>
    public static T DataContractSerializationRoundTrip<T>(T obj, 
                    IEnumerable<Type> knownTypes)
    {
        var serializer = new DataContractSerializer(obj.GetType(), knownTypes);
        var memoryStream = new MemoryStream();
        serializer.WriteObject(memoryStream, obj);
        memoryStream.Position = 0;
        obj = (T)serializer.ReadObject(memoryStream);
        return obj;
    }
}

Две задачи, за которые вы отвечаете:

  • Заполнение экземпляра в первую очередь разумными данными. Вы можете использовать отражение для установки свойств или снабдить конструктор своими аргументами, но я нашел, что этот подход просто не будет работать ни на что иное, кроме невероятно простых типов.
  • Сравнивая два экземпляра после того, как вы совершили круговое де-сериализацию. Если у вас надежная реализация Equals/GetHashCode, то это уже может быть сделано для вас. Опять же, вы можете попробовать использовать общий отражающий компаратор, но это может быть не совсем надежным.