C# 字符串比较断言在看起来应该通过时失败

C# 字符串比较断言在看起来应该通过时失败,c#,json.net,string-comparison,xunit,fluent-assertions,C#,Json.net,String Comparison,Xunit,Fluent Assertions,我有一个测试来检查一个项目是否被正确序列化 public interface IMyJsIdentity { string Forename { get; } string Surname { get; } string Guid { get; } } public class MyIdentity : IMyJsIdentity { public string Forename { get; set; } public

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

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

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

我刚测试过,结果的值是:

{“名字”:“名字”,“姓氏”:“姓氏”,“Guid”:“abcdefghijk”,“Id”:0}

这将很自然地违反您预期的一系列:

“{{\'Forename\':\'Forename\',\'Lastname\':\'Lastname\',\'Guid\':\'abcdefghijk\'}”

使用双大括号是一个转义序列,仅适用于
String.format
方法中使用的格式化字符串,因此可以包含一个大括号。从:

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

如果未使用
String.Format
,则双大括号将按照的字面解释为两个大括号,因为它不是字符串文字的转义字符

由此产生的错误消息令人困惑。我不确定这是因为调试器是如何向GUI报告的,还是因为调试器在格式化错误消息时出现了错误(可能是因为它们对输出的转义括号过于激进),或者是什么原因

如果您将测试更改为:

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

我想那会过去的。这可以通过使用
String.Format
调用的附加测试进行备份,该调用将双大括号更改为单大括号。现在,如果您打算在JSON上使用双大括号,那完全是另一个问题,但我怀疑这不是您的意图。

我刚刚测试过,
结果的值是:

{“名字”:“名字”,“姓氏”:“姓氏”,“Guid”:“abcdefghijk”,“Id”:0}

这将很自然地违反您预期的一系列:

“{{\'Forename\':\'Forename\',\'Lastname\':\'Lastname\',\'Guid\':\'abcdefghijk\'}”

使用双大括号是一个转义序列,仅适用于
String.format
方法中使用的格式化字符串,因此可以包含一个大括号。从:

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

如果未使用
String.Format
,则双大括号将按照的字面解释为两个大括号,因为它不是字符串文字的转义字符

由此产生的错误消息令人困惑。我不确定这是因为调试器是如何向GUI报告的,还是因为调试器在格式化错误消息时出现了错误(可能是因为它们对输出的转义括号过于激进),或者是什么原因

如果您将测试更改为:

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

我想那会过去的。这可以通过使用
String.Format
调用的附加测试进行备份,该调用将双大括号更改为单大括号。现在,如果您打算在JSON周围使用双大括号,那完全是另一个问题,但我怀疑这不是您的意图。

尝试调试它并查看两个字符串的内部字符数组,这可能会给您一个asnwer,说明可能有什么问题。我想问题出在您的“.Should().be()”方法中。这些字符串的长度完全相同,但它报告它们是不同的。可能是因为较长的一个正在计算引号?有没有理由使用双引号
{{
}
?如果在某个地方对该字符串进行了
String.Format
调用,它会将这些字符串转换为单个大括号。这也可能是输出消息中的一点错误信息/放置额外大括号时出错。编辑:类似地,如果您没有使用
String.Format
调用,则双大括号根本不作为转义字符,除非您打算使用两个大括号,否则不应将它们加倍。请尝试调试它,并查看两个字符串的内部字符数组,这可能会给您一个错误提示。我想问题出在您的“.Should().be()”方法中。这些字符串的长度完全相同,但它报告它们不同。可能是因为较长的一个正在计算引号?有没有理由使用双引号
{{
}
?如果在某个地方对该字符串进行了
String.Format
调用,它会将这些字符串转换为单个大括号。这也可能是输出消息中的一点错误信息/放置额外大括号时出错。编辑:类似地,如果您没有使用
String.Format
调用,则双大括号根本不作为转义字符,除非您打算使用两个大括号,否则不应将它们加倍。您完全正确,谢谢。我陷入了一个陷阱,让它失败,然后只是把我的期望从测试失败窗口复制出来。你完全正确,谢谢你。我陷入了一个陷阱,让它失败,然后把我的期望从测试失败窗口复制出去。