How to unit test if my object is really serializable?

I am using C # 2.0 with Nunit Test. I have some object that needs to be serialized. These objects are quite complex (inheritance at different levels and contains many objects, events and delegates).

How can I create a Unit Test to make sure my object is safe to serializable?

+27
c # serialization unit-testing
Oct. 25 '08 at 15:47
source share
7 answers

I have this in some unit test here on the assignment:

MyComplexObject dto = new MyComplexObject(); MemoryStream mem = new MemoryStream(); BinaryFormatter b = new BinaryFormatter(); try { b.Serialize(mem, dto); } catch (Exception ex) { Assert.Fail(ex.Message); } 

It may help ... maybe another method might be better, but this one works well.

+12
Oct. 25 '08 at 15:47
source share

Here is a general way:

 public static Stream Serialize(object source) { IFormatter formatter = new BinaryFormatter(); Stream stream = new MemoryStream(); formatter.Serialize(stream, source); return stream; } public static T Deserialize<T>(Stream stream) { IFormatter formatter = new BinaryFormatter(); stream.Position = 0; return (T)formatter.Deserialize(stream); } public static T Clone<T>(object source) { return Deserialize<T>(Serialize(source)); } 
+38
Oct 25 '08 at 17:04
source share

In addition to the above test, which ensures that the serializer accepts your object, you need to run a round-trip test. Detach the results to a new object and make sure that both instances are equivalent.

+13
Oct 25 '08 at 15:54
source share

serialize the object (to memory or disk), deserialize it, use reflection to compare the two, then run all the unit tests for this object again (except for serialization)

this suggests that your unit tests may take an object as a target instead of creating your own

+3
Oct. 25 '08 at 16:19
source share

Here is a solution that recursively uses IsSerializable to verify that the object and all its properties are Serializable.

  private static void AssertThatTypeAndPropertiesAreSerializable(Type type) { // base case if (type.IsValueType || type == typeof(string)) return; Assert.IsTrue(type.IsSerializable, type + " must be marked [Serializable]"); foreach (var propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (propertyInfo.PropertyType.IsGenericType) { foreach (var genericArgument in propertyInfo.PropertyType.GetGenericArguments()) { if (genericArgument == type) continue; // base case for circularly referenced properties AssertThatTypeAndPropertiesAreSerializable(genericArgument); } } else if (propertyInfo.GetType() != type) // base case for circularly referenced properties AssertThatTypeAndPropertiesAreSerializable(propertyInfo.PropertyType); } } 
+2
Nov 01 '10 at 18:23
source share

Unfortunately, you cannot verify this. Imagine this case:

 [Serializable] class Foo { public Bar MyBar { get; set; } } [Serializable] class Bar { int x; } class DerivedBar : Bar { } public void TestSerializeFoo() { Serialize(new Foo()); // OK Serialize(new Foo() { MyBar = new Bar() }; // OK Serialize(new Foo() { MyBar = new DerivedBar() }; // Boom } 
+1
Dec 16 '10 at 19:09
source share

Maybe a little late, but if you use the FluentAssertions library, then it has custom assertions for XML serialization, binary serialization, and serialization of data contracts.

 theObject.Should().BeXmlSerializable(); theObject.Should().BeBinarySerializable(); theObject.Should().BeDataContractSerializable(); theObject.Should().BeBinarySerializable<MyClass>( options => options.Excluding(s => s.SomeNonSerializableProperty)); 
0
Jul 03 '17 at 3:49 on
source share



All Articles