Question

J'ai un test pour vérifier qu'un article est correctement sérialisé

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

Cependant j'obtiens l'erreur suivante sur l'échec du test

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.

Il y a clairement quelque chose de spécial que Json.net fait à la chaîne, mais je n'arrive pas à comprendre quoi.

Bizarrement ça passe

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

Je suppose que ce n'est pas grave mais j'aimerais savoir pourquoi.

Était-ce utile?

La solution

Je viens de tester et la valeur de result est:

{"Prénom": "prénom", "Nom": "nom de famille", "Guid": "abcdefghijk", "Id": 0}

Ce qui échouera naturellement par rapport à votre chaîne attendue de :

"{{\"Prénom\":\"prénom\",\"Nom\":\"nom\",\"Guid\":\"abcdefghijk\"}}"

L'utilisation d'accolades doubles est une séquence d'échappement uniquement pour les chaînes de format utilisées dans le String.Format méthode afin que vous puissiez inclure un célibataire entretoise.Du Page MSDN de formatage composite:

Les accolades d'ouverture et de fermeture sont interprétées comme démarrant et terminant un élément de format.Par conséquent, vous devez utiliser une séquence d'évasion pour afficher une attelle d'ouverture littérale ou une attelle de fermeture.Spécifiez deux accolades d'ouverture ("{{") dans le texte fixe pour afficher une orthèse d'ouverture ("{"), ou deux accolades de fermeture ("}}") pour afficher un accolade de fermeture ("}").

Si vous n'utilisez pas String.Format, alors la double accolade sera interprétée littéralement comme deux accolades selon le Spécification C# 2.4.4.5 puisqu'il ne s'agit pas d'un caractère d'échappement pour les chaînes littérales.

Le message d'erreur qui en résulte prête à confusion.Je ne sais pas si cela est dû à la façon dont le débogueur le signale à l'interface graphique, ou à une erreur dans la façon dont il formate son message d'erreur (peut-être qu'ils sont trop agressifs en évitant les accolades pour la sortie), ou quoi.

Si vous modifiez votre test pour qu'il soit :

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

Ensuite, ça passera, je suppose.Ceci est sauvegardé par votre test supplémentaire en utilisant le String.Format appel qui change vos doubles accolades en accolades simples.Maintenant, si vous aviez l'intention d'avoir des accolades doubles autour de votre JSON, c'est un tout autre problème, mais je soupçonne que ce n'est pas votre intention.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top