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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top