Comparação de seqüência de caracteres de declaração de falha quando parece que deve passar
-
21-12-2019 - |
Pergunta
Eu tenho um teste para verificar se um item é serializado corretamente
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\"}}"
);
}
No entanto, recebo o seguinte erro sobre a falha de teste
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.
Há claramente algo de especial, que Json.net é fazer para a cadeia, mas eu não consigo descobrir o que.
Estranhamente, este passa
result.Should().Be(
String.Format("{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}")
);
Eu acho que não é um grande negócio, mas eu gostaria de saber o por que.
Solução
Acabo de testar e o valor de result
é:
{"Nome":"nome","Apelido":"sobrenome","Guid":"abcdefghijk","Id":0}
O que será, naturalmente, falhar contra o seu seqüência esperada de:
"{{\"Nome\":\"nome\",\"Nome\":\"nome\",\"Guid\":\"abcdefghijk\"}}"
Usando chaves duplas é uma seqüência de escape apenas para cadeias de caracteres de formato usado no String.Format
método, de modo que você pode incluir uma único cinta.Do Composto de Formatação de página MSDN:
Abertura e fechamento de chaves são interpretados como iniciar e terminar uma item formato.Conseqüentemente, você deve usar uma seqüência de escape para exibir um literal chave de abertura ou fechamento.Especificar duas chaves de abertura ("{{") no texto fixo para exibir uma chave de abertura ("{"), ou dois chaves de fechamento ("}}") para exibir uma chave de fechamento ("}").
Se você não estiver usando String.Format
, e , em seguida, a dupla cinta vai ser interpretado literalmente como duas chavetas, conforme o C# Especificação De 2.4.4.5 pois ele não é um caractere de escape para literais de seqüência de caracteres.
A resultante mensagem de erro é confuso.Eu não tenho certeza se isto é devido a como o depurador está relatórios para o GUI, ou um erro com a forma como eles são a formatação de sua mensagem de erro (talvez eles são muito agressivos e escapar chaves para a saída), ou o que seja.
Se você alterar o teste para ser:
result.Should().Be(
"{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}"
);
Em seguida, ele vai passar eu suspeito.Este é apoiado por seu teste adicional, usando o String.Format
chamada, o que altera sua duplo chaves para um único aparelho.Agora, se você pretende ter o dobro de moldagem de chaves em torno de seu JSON, que é outra questão inteiramente, mas eu suspeito que isso não é a sua intenção.