2

I have a test for checking that an item is serialized correctly

public interface IMyJsIdentity
{
    string Forename { get; }
    string Surname { get; }
    string Guid { get; }                 
}

public class MyIdentity : IMyJsIdentity
{
    public string Forename { get; set; }
    public string Surname { get; set; }
    public string Guid { get; set; }
    public int Id { get; set; }
}

[Fact]
public void SerialiseCorrectly()
{
    // Arrange
    MyIdentity identity = new MyIdentity()
    {
        Forename = "forename",
        Surname = "surname",
        Guid = "abcdefghijk"
    };

    // Act
    string result = JsonConvert.SerializeObject(
        identity, 
        new JsonSerializerSettings()
        {
            ContractResolver = new InterfaceContractResolver(typeof(IMyJsIdentity))
        });

    // Assert
    result.Should().Be(
        "{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}"
        );
}

However I get the following error on the test failure

Xunit.Sdk.AssertException: Expected string to be 
"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}" with a length of 66, but 
"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}" has a length of 64.

There's clearly something special that Json.net is doing to the string but I can't figure out what.

Weirdly this passes

result.Should().Be(
    String.Format("{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}")
    );

I guess it's not a big deal but I'd like to know why.

Neil
  • 5,179
  • 8
  • 48
  • 87
  • try debugging it and see the internal char array of the two strings, that might give you an asnwer what might be wrong. – Mario Stoilov Jan 09 '14 at 12:45
  • 1
    I would suppose the problem is in your '.Should().Be()' method. Those strings are the exact same length but it is reporting that they are different. Possibly because the longer one is counting the quotation marks? – MaineCoder Jan 09 '14 at 12:45
  • Any reason to have the double `{{` and `}}`? If a `String.Format` call is made on that string somewhere, it will convert those to single curly braces. This could also be a bit of misinformation in the output message/error putting extra curly braces. EDIT: Similarly, if you aren't using a `String.Format` call, then the double braces don't serve as escape characters at all and you should not double them up unless you intend to have 2 braces. – Chris Sinclair Jan 09 '14 at 13:04

1 Answers1

4

I just tested and the value of result is:

{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk","Id":0}

Which will naturally fail against your expected string of:

"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}"

Using double curly braces is an escape sequence only for format strings used in the String.Format method so that you may include a single brace. From the Composite Formatting MSDN page:

Opening and closing braces are interpreted as starting and ending a format item. Consequently, you must use an escape sequence to display a literal opening brace or closing brace. Specify two opening braces ("{{") in the fixed text to display one opening brace ("{"), or two closing braces ("}}") to display one closing brace ("}").

If you aren't using String.Format, then the double brace will be interpreted literally as two braces as per the C# Specification 2.4.4.5 since it is not an escape character for string literals.

The resultant error message is confusing. I'm not sure if this is because how the debugger is reporting it to the GUI, or an error with how they are formatting their error message (perhaps they are overly aggressive escaping braces for output), or what.

If you change your test to be:

result.Should().Be(
        "{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}"
        );

Then it will pass I suspect. This is backed up by your additional test using the String.Format call which changes your double braces to single braces. Now, if you intended to have double wrapping braces around your JSON, that's another issue entirely, but I suspect that that isn't your intent.

Chris Sinclair
  • 22,858
  • 3
  • 52
  • 93
  • you're absolutely right, thanks for that. I fell into the trap of letting it fail and then just copying my expectation out of the test failure window. – Neil Jan 09 '14 at 14:05