0

I am using the protobuf-net library for serialization/deserialization of messages.

Due to the distributed nature of the application some applications will have an older version of the object that is being used to serialize messages. The cases I'm concerned with are

  • adding new fields to the message object that some consumers(deserializers) won't have

  • removing fields in the message object that some consumers(deserializers) will still have.

Example an old app has this definition of Foo

class Foo
{
 public int Field1 {get; set;}
}

A newer app has this definition of Foo

class Foo
{
 public int Field1 {get; set;}
 public int Field2 {get; set;}
}

I want to have a test to verify that the library can deserialize an object with missing fields and fields that it isn't aware of in case I ever need to change my serialization library.

Is there an easy way to unit test this? C# won't let the user change the fields availabe in an object.

Currently I have to build my reciever app and then change the object that is transported to add a new field and then build my sending app to test this.

Is there a better way?

asked Jan 19, 2016 at 15:37
6
  • What kind of information do you want to obtain from the test? Which fields have been added or removed (a "diff")? Whether two serializations are functionally equal? You haven't made that clear in you're question; all you've said is "verify how the library works." What does "how the library works" mean? Commented Jan 19, 2016 at 15:41
  • You'll have to make sure to keep track of version you're using and then drop/add the fields as necessary. There's not much you can do except keeping up with the API changes that may or may not break things. It's very difficult. Commented Jan 19, 2016 at 15:44
  • @RobertHarvey I thought it was clear that I want to ensure that deserialization still works event though its missing a field or it has an extra field. I'll try to reword the question. Commented Jan 19, 2016 at 15:49
  • 1
    Make two objects, remove a field from one object, serialize the first object, deserialize it to the second object, observe the results. (???) I guess I should have asked "What do you mean by 'better'?" Commented Jan 19, 2016 at 15:51
  • 1
    You don't need dynamic objects to make this test work. You just need two ordinary classes. (????) In fact, you have two such classes in your question. Commented Jan 19, 2016 at 15:55

3 Answers 3

9

Your deserialization test should take a String as its input, and try to produce a present-day object from it. Therefore, all you have to do is revert a copy of your project to an earlier state, save a serialized String, return to the head, and put that string into your test data. Unless I misunderstand your question, you never need to have different versions of the same class actually compiled in your code base.

answered Jan 19, 2016 at 15:43
1
  • @Killian That sounds like a promising approach. I could serialize objects with additional fields and missing fields to test how the deserializing works with the different serialized form. Commented Jan 19, 2016 at 15:51
2

Maybe a little bit late, but I will answer for those who came across this question from search. I suggest using FluentAssertions library that provides an easy way of testing whether an object is serializable using one of the common serializations: Xml, Binary and DataContract:

using FluentAssertions;
theObject.Should().BeXmlSerializable();
theObject.Should().BeBinarySerializable();
theObject.Should().BeDataContractSerializable();
theObject.Should().BeBinarySerializable<MyClass>(
 options => options.Excluding(s => s.SomeNonSerializableProperty));
kevin cline
33.8k3 gold badges73 silver badges143 bronze badges
answered Oct 18, 2017 at 5:36
0

Every time you change the dataformat save an item with a standartized content to a dataformat-regression-folder together with a human-readable-version (i.e. xml) as expected result.

so you have file pairs of version-1.0.dat and version-1.0.dat.xml

Then write a regression-test that loops over all files in dataformat-regression-folder.

Pseudocode looks like this:

 foreach(String samplePath in LoadSamplePaths("dataformat-regression-folder\\*.dat"))
 {
 MyDataFormat sample = LoadSample(samplePath);
 MyDataFormat expected = LoadFromXml(samplePath + ".xml");
 assertEqual(sample.toXml(), expected.toXml());
 }
answered Oct 18, 2017 at 10:55

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.