Утверждение сравнения строк не работает, хотя кажется, что оно должно пройти

StackOverflow https://stackoverflow.com//questions/21020570

Вопрос

У меня есть тест для проверки правильности серийного номера товара.

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

Я думаю, это не имеет большого значения, но мне хотелось бы знать, почему.

Это было полезно?

Решение

Я только что проверил и значение result является:

{"Имя":"имя","Фамилия":"фамилия","Guid":"abcdefghijk","Id":0}

Что, естественно, потерпит неудачу в отношении ожидаемой строки:

"{{\"Имя\":\"имя\", \"Фамилия\":\"фамилия\", \"Guid\":\"abcdefghijk\"}}"

Использование двойных фигурных скобок является escape-последовательностью только для строк формата, используемых в String.Format метод, чтобы вы могли включить одинокий скобка.Из Страница MSDN составного форматирования:

Открытие и закрытие скобок интерпретируется как запуск и заканчивает элемент формата.Следовательно, вы должны использовать последовательность побега, чтобы отобразить буквальную открывающуюся скобу или закрывающуюся скобу.Укажите два открытия скоб ("{{") в фиксированном тексте, чтобы отобразить одну открывающуюся скобу ("{") или две закрывающие брекеты ("}}"), чтобы отобразить одну закрывающуюся скобку ("}").

Если вы не используете String.Format, то двойная скобка будет интерпретироваться буквально как две скобки согласно Спецификация С# 2.4.4.5 поскольку это не escape-символ для строковых литералов.

Полученное сообщение об ошибке сбивает с толку.Я не уверен, связано ли это с тем, как отладчик сообщает об этом в графический интерфейс, или с ошибкой форматирования сообщения об ошибке (возможно, они слишком агрессивно экранируют фигурные скобки для вывода), или с чем-то еще.

Если вы измените свой тест на:

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

Потом пройдет, я подозреваю.Это подтверждается вашим дополнительным тестом с использованием String.Format вызов, который заменяет ваши двойные скобки одинарными.Теперь, если вы намеревались использовать двойные скобки вокруг вашего JSON, это совсем другая проблема, но я подозреваю, что это не ваша цель.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top