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:
string template = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
expected, actual, message);
Ensuite, nous utilisons string.Format
avec les paramètres que vous avez fournis:
string finalMessage = string.Format(template, parameters);
(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:
{Width=0, Height=0}
Ainsi, le deuxième niveau de formatage est quelque chose comme:
string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
"Message = Failed expected {0} actually is {1}", struct1, struct2);
... 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:
var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");
Le résultat est:
Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!
Clairement cassé, car nous ne nous attendions pas, foo
ni la valeur réelle bar
!
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.
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
, struct1.ToString (), struct2.ToString ())) `?