J'essaye d'affirmer l'égalité de deux System.Drawing.Size
structures, et j'obtiens une exception de format au lieu de l'échec d'assertion attendu.
[TestMethod]
public void AssertStructs()
{
var struct1 = new Size(0, 0);
var struct2 = new Size(1, 1);
//This throws a format exception, "System.FormatException: Input string was not in a correct format."
Assert.AreEqual(struct1, struct2, "Failed. Expected {0}, actually it is {1}", struct1, struct2);
//This assert fails properly, "Failed. Expected {Width=0, Height=0}, actually it is {Width=1, Height=1}".
Assert.AreEqual(struct1, struct2, "Failed. Expected " + struct1 + ", actually it is " + struct2);
}
Est-ce un comportement prévu? Est-ce que je fais quelque chose de mal ici?
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
, struct1.ToString (), struct2.ToString ())) `?Réponses:
J'ai compris. Et oui, c'est un bug.
Le problème est qu'il y a deux niveaux de fonctionnement
string.Format
ici.Le premier niveau de formatage est quelque chose comme:
Ensuite, nous utilisons
string.Format
avec les paramètres que vous avez fournis:(De toute évidence, des cultures sont fournies, et une sorte de désinfection ... mais pas assez.)
Cela semble correct - à moins que les valeurs attendues et réelles elles-mêmes se retrouvent avec des accolades après avoir été converties en chaîne - ce qu'elles font
Size
. Par exemple, votre première taille finit par être convertie en:Ainsi, le deuxième niveau de formatage est quelque chose comme:
... et c'est ce qui échoue. Aie.
En effet, nous pouvons le prouver très facilement en trompant le formatage pour utiliser nos paramètres pour les parties attendues et réelles:
Le résultat est:
Clairement cassé, car nous ne nous attendions pas,
foo
ni la valeur réellebar
!Fondamentalement, c'est comme une attaque par injection SQL, mais dans le contexte un peu moins effrayant de
string.Format
.Pour contourner le problème, vous pouvez utiliser
string.Format
comme le suggère StriplingWarrior. Cela évite que le deuxième niveau de formatage soit effectué sur le résultat du formatage avec les valeurs réelles / attendues.la source
%*n
équivalent? :(Je pense que vous avez trouvé un bug.
Cela fonctionne (lève une exception assert):
Et cela fonctionne (affiche le message):
Mais cela ne fonctionne pas (lance un
FormatException
):Je ne vois aucune raison pour laquelle ce serait un comportement attendu. Je soumettrais un rapport de bogue. En attendant, voici une solution de contournement:
la source
Je suis d'accord avec @StriplingWarrior que cela semble effectivement être un bogue avec la méthode Assert.AreEqual () sur au moins 2 surcharges. Comme StiplingWarrior l'a déjà souligné, ce qui suit échoue;
J'ai fait un peu d'expérimentation à ce sujet pour être un peu plus explicite dans l'utilisation du code. Ce qui suit ne fonctionne pas non plus;
Et
Cela m'a fait réfléchir. System.Drawing.Size est une structure. Et les objets? La liste des param ne précise que la liste après le
string
message estparams object[]
. Techniquement, les structures yes sont des objets ... mais des types d'objets spéciaux , c'est-à-dire des types valeur. Je pense que c'est là que réside le bogue. Si nous utilisons notre propre objet avec un usage similaire et structureSize
, ce qui suit en fait fait le travail;la source
class
oustruct
, mais si laToString
valeur contient des accolades ressemblant à unString.Format
.Je pense que la première affirmation est incorrecte.
Utilisez plutôt ceci:
la source