2

我有一个检查项目是否正确序列化的测试

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\"}}"
        );
}

但是我在测试失败时收到以下错误

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.

Json.net 显然对字符串做了一些特别的事情,但我不知道是什么。

奇怪的是,这过去了

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

我想这没什么大不了的,但我想知道为什么。

4

1 回答 1

4

我刚刚测试过,值为result

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

这自然会与您预期的字符串失败:

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

使用双花​​括号是仅用于String.Format方法中使用的格式字符串的转义序列,因此您可以包含单个大括号。从复合格式 MSDN 页面

左大括号和右大括号被解释为格式项的开始和结束。因此,您必须使用转义序列来显示文字左大括号或右大括号。在固定文本中指定两个左大括号(“{{”)以显示一个左大括号(“{”),或两个右大括号(“}}”)以显示一个右大括号(“}”)。

如果您不使用,则根据C# 规范 2.4.4.5String.Format,双大括号将按字面意思解释为两个大括号,因为它不是字符串文字的转义字符。

由此产生的错误消息令人困惑。我不确定这是否是因为调试器如何将其报告给 GUI,或者他们如何格式化错误消息(也许他们过于激进地转义输出大括号),或者是什么。

如果您将测试更改为:

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

然后它会通过我怀疑。String.Format这由您使用将双括号更改为单括号的调用的附加测试来支持。现在,如果您打算在 JSON 周围使用双括号,那完全是另一个问题,但我怀疑这不是您的意图。

于 2014-01-09T13:16:26.583 回答