1

I have a custom exception that takes in a couple strings in the ctor followed by the usual Exception innerException last parameter. The exception class is decorated with [Serializable]. This exception class MyException also inherits from MyBaseException which in turn inherits from Exception.

I'm trying to unit test that all the ctor parameters hydrate and dehydrate properly. This works:

var error = new MyException("entityname1");
error.Should().BeBinarySerializable();

This does not work:

var error = new MyException("entityname1",
    new InvalidOperationException("some error"));
error.Should().BeBinarySerializable();

It gives:

Expected MyException with message "Unable to sign-in “entityname1”."
 to be serializable, but serialization failed with:

Expected member InnerException
to be System.InvalidOperationException with message \"some error\"\n,
but found System.InvalidOperationException with message \"some error\"

The error being thrown has no innerException information that might give an idea of the problem.

Interestingly, this works:

var error = new MyException("entityname1", new MyOtherException("some error"));

Any idea why that one serialization fails and/or how to debug the problem?

.NET 4.6.1 and FluentAssertions 4.14.0

EDIT:

Given what @Evk discovered, I tried manually serializing/deserializing an Exception with the BinaryFormatter and it seems to work fine:

var formatter = new BinaryFormatter();

var source = new Exception("some error");

byte[] buffer;
using (var stream = new MemoryStream())
{
    formatter.Serialize(stream, source);

    buffer = new byte[stream.Length];

    stream.Position = 0;
    stream.Read(buffer, 0, buffer.Length);
}

using (var stream = new MemoryStream(buffer))
{
    var ex = (Exception)formatter.Deserialize(stream);

    ex.ToString().Should().Be(source.ToString());
}

So maybe this is a bug in FluentAssertions.

Glenn Doten
  • 2,603
  • 3
  • 21
  • 22
  • Try throwing the inner exception first and checking it in a catch? (this is just a random guess). Also, have you checked [their bug log](https://github.com/dennisdoomen/fluentassertions/issues), perhaps even file one of your own? – Scott Chamberlain Oct 05 '16 at 19:30
  • Do all of your custom exception types have streaming constructors, as is shown to be required in [this question](https://stackoverflow.com/questions/3422703/how-to-deserialize-object-derived-from-exception-class-using-json-net-c)? That question is about Json.NET but `BinaryFormatter` uses the same constructor for exception serialization. Unlike in that question, `BinaryFormatter` requires your constructor to call the `base` constructor. – dbc Oct 05 '16 at 19:48
  • Actually the same is reproducable with just "new Exception("some error").Should().BeBinarySerializable();", so it's some bug in FluentAssertion library, not that your exceptions are really not serializable. – Evk Oct 05 '16 at 19:50
  • @ScottChamberlain same thing happens if the InvalidOperationException is thrown before adding it to the exception. – Glenn Doten Oct 05 '16 at 20:01
  • @dbc Yup, they all have the streaming ctor and the GetObjectData method. The exceptions all work as expected except FluentAssertions doesn't seem to like the innerException being non-null. – Glenn Doten Oct 05 '16 at 20:02
  • @gdoten that's because it doesn't like _any_ default exceptions (Exception, InvalidOperationException and so on) it seems, see my comment above. – Evk Oct 05 '16 at 20:28

1 Answers1

0

This has been fixed in FluentAssertions:

BeBinarySerializable fails with standard .NET exceptions, but not with custom exceptions

Glenn Doten
  • 2,603
  • 3
  • 21
  • 22