Je suis en train d’affirmer l’égalité des deux `` des structures et je me fais un format exception au lieu de l’attendre affirmer échec.
Est ce comportement prévu ? J’ai fais quelque chose de mal ici ?
Je suis en train d’affirmer l’égalité des deux `` des structures et je me fais un format exception au lieu de l’attendre affirmer échec.
Est ce comportement prévu ? J’ai fais quelque chose de mal ici ?
Je l'ai. Et oui, c'est un bug.
Le problème, c'est qu'il y a deux niveaux d' string.Format
passe ici.
Le premier niveau de mise en forme 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 fourni:
string finalMessage = string.Format(template, parameters);
(Évidemment il y a des cultures qui sont fournis, et certains de tri de nettoyage... mais pas assez.)
Qui a l'air bien, à moins que les attendus et les valeurs réelles eux-mêmes jusqu'à la fin avec les accolades, après avoir été converti en une chaîne à qui ils le font pour d' Size
. Par exemple, votre première taille finit par être converti à:
{Width=0, Height=0}
Donc le deuxième niveau de mise en forme 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);
... ce qui est en faillite. Ouch.
En effet, nous pouvons le prouver très facilement en trompant la mise en forme à l'utilisation de nos paramètres pour les attendus et réels pièces:
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é, que l'on n'attendait pas foo
ni était la valeur réelle bar
!
En gros, cela ressemble à une attaque par injection SQL, mais en un peu moins effrayant contexte de l' string.Format
.
Comme solution de contournement, vous pouvez utiliser string.Format
comme StriplingWarrior suggère. Qui évite que le deuxième niveau de mise en forme étant effectuée sur le résultat de la mise en forme avec des valeurs.
Je pense que vous avez trouvé un bug.
Cela fonctionne (lève une exception d’assert) :
Et cela fonctionne (renvoie le message) :
Mais cela ne fonctionne pas (lève une `` ) :
Je ne vois aucune raison pour que ce serait le comportement attendu. Je dirais un rapport de bogue. En attendant, voici une solution de contournement :
Je suis d'accord avec @StriplingWarrior que cela ne semble en effet avoir un problème avec l'Affirmer.AreEqual() la méthode sur au moins 2 des surcharges. Comme StiplingWarrior l'a déjà souligné, le suivant ne fonctionne pas;
var a = new { c = 1 };
var b = new { c = 2 };
Assert.AreEqual(a, b, "Not equal {0} {1}", a, b);
J'ai fait un peu d'expérience sur ce sujet ultérieurement être un peu plus explicite dans le code d'utilisation. Le suivant ne fonctionne pas non plus;
// specify variable data type rather than "var"...no effect, still fails
Size a = new Size(0, 0);
Size b = new Size(1, 1);
Assert.AreEqual(a, b, "Not equal {0} {1}", a, b);
Et
// specify variable data type and name the type on the generic overload of AreEqual()...no effect, still fails
Size a = new Size(0, 0);
Size b = new Size(1, 1);
Assert.AreEqual<Size>(a, b, "Not equal {0} {1}", a, b);
Cela m'a fait réfléchir. Système.De dessin.La taille est une struct. Que sur les objets? Le param liste ne spécifier que la liste après l' string
message params object[]
. Techniquement, oui les structures sont des objets...mais des sortes d'objets, c'est à dire, des types de valeur. Je pense que c'est là que le bug se trouve. Si nous utilisons notre propre objet avec un analogue de l'utilisation et de la structure d' Size
, le suivant en fait ne travail;
private class MyClass
{
public MyClass(int width, int height)
: base()
{ Width = width; Height = height; }
public int Width { get; set; }
public int Height { get; set; }
}
[TestMethod]
public void TestMethod1()
{
var test1 = new MyClass(0, 0);
var test2 = new MyClass(1, 1);
Assert.AreEqual(test1, test2, "Show me A [{0}] and B [{1}]", test1, test2);
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.