Ho capito. E sì, è un bug.
Il problema è che ci sono due livelli in string.Formatcorso 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.Formatcon 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 fooné 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.Formatcome 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 ())) `?