Ho capito. E sì, è un bug.
Il problema è che ci sono due livelli in string.Format
corso qui.
Il primo livello di formattazione è qualcosa del tipo:
string template = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
expected, actual, message);
Quindi usiamo string.Format
con i parametri che hai fornito:
string finalMessage = string.Format(template, parameters);
(Ovviamente vengono fornite culture e una sorta di sanificazione ... ma non abbastanza.)
Sembra a posto, a meno che i valori attesi ed effettivi non finiscano con le parentesi graffe, dopo essere stati convertiti in una stringa, cosa che fanno Size
. Ad esempio, la tua prima taglia finisce per essere convertita in:
{Width=0, Height=0}
Quindi il secondo livello di formattazione è qualcosa del tipo:
string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
"Message = Failed expected {0} actually is {1}", struct1, struct2);
... ed è questo che sta fallendo. Ahia.
In effetti, possiamo dimostrarlo molto facilmente ingannando la formattazione per utilizzare i nostri parametri per le parti previste ed effettive:
var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");
Il risultato è:
Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!
Chiaramente rotto, come non ci aspettavamo foo
né il valore effettivo bar
!
Fondamentalmente questo è come un attacco SQL injection, ma nel contesto un po 'meno spaventoso di string.Format
.
Come soluzione alternativa, puoi usare string.Format
come suggerisce StriplingWarrior. Ciò evita che il secondo livello di formattazione venga eseguito sul risultato della formattazione con i valori effettivi / previsti.
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
, struct1.ToString (), struct2.ToString ())) `?