Testing serializable

Does NServicebus testing provide some tools to test if my Events and Commands will serialize and deserialize probably? I would like to test this in our test suite, that does not have a running NServicebus.

I would like to assert an error when someone commits Messages with e.g. private setters or no setters.

Hi @Stig_Christensen,

No, we don’t, but I’m not sure you really need NServiceBus stuff for that. That sounds like a reflection-based test to me.

The serializer classes themselves are mostly marked internal, like Newtonsoft here and also depend on things like IMessageMapper which I wouldn’t want you to have to mock anyway. Plus then you’d have to fill each message type with fake data to try serializing it and deserializing it—I’m sure just checking all the properties with Reflection would be easier and more direct anyway.

OK but if I wrote this test myself, I had to mimic the NServicebus serializer and also remember to check if it has changed with every new version of NServicebus. Or am I missing something here?

I don’t think you should try to mimic anything. Don’t actually try to serialize or deserialize anything, because then you’ll have to come up with fake data for every single message type you want to test.

Instead, just test each type for the set of rules (like no private setters) you’ve decided you want to enforce for each message type.

In pseudocode:

foreach (var type in GetTypesThatAreMessages())
{
    foreach (var property in type.GetProperties())
    {
        // Assert that property has a setter
        // Assert that setter is not private
    }
}

That’s not going to change just becuase NServiceBus does.

I could do that, but is it guaranteed that these are the rules? (the answer is no)

Actually I found out that is was not due to private setters, but instead due to an extra empty constructor. :frowning:

The following will not deserialize correct and Text1 + Text2 will be null in my MessageHandlers (NSB version 7.4.4)

internal class TestCommand : ICommand
{
	public string Text1 { get; private set; }
	public string Text2 { get; private set; }
	public TestCommand() { }
	public TestCommand(string text1, string text2)
	{
		Text1 = text1;
		Text2 = text2;
	}
}

Also this will mix the text-properties when deserialized (notice no empty constructor, but changed argument order)

internal class TestCommand : ICommand
{
	public string Text1 { get; private set; }
	public string Text2 { get; private set; }
	public TestCommand(string text2, string text1)
	{
		Text1 = text1;
		Text2 = text2;
	}
}

I cannot seem to find anything in the documentation about message constructors and how they behave.

Every serializer is different. Some can deal with private setters, some can’t. But all of them have to obey the rules of C#. A serializer needs to instantiate a class and then fill its properties with data. How is it supposed to do that when the only constructor you give it is something with parameters it doesn’t know how to fill?

The safest thing is only public properties with public setters and no custom constructors.

This is really just standard .NET serialization concepts. It doesn’t really have much to do specifically with NServiceBus at all.

Every serializer is different

I agree, and that is why I read the documentation and/or use a test/tool to verify that it will work.

The safest thing is only public properties with public setters and no custom constructors.

Again I agree, but also we want to ensure that every Command is the a correct state (all state via the constructor)

This is really just standard .NET serialization concepts. It doesn’t really have much to do specifically with NServiceBus at all.

That is a bit contradictory using the word “standard” :slight_smile:

I now see we are using

endpointConfiguration.UseSerialization<NewtonsoftSerializer>();

so I will dig into their documentation