Ich habe es. Und ja, es ist ein Fehler.
Das Problem ist, dass es hier zwei Ebenen gibt string.Format
.
Die erste Formatierungsstufe ist wie folgt:
string template = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
expected, actual, message);
Dann verwenden wir string.Format
mit den von Ihnen angegebenen Parametern:
string finalMessage = string.Format(template, parameters);
(Offensichtlich werden Kulturen bereitgestellt und eine Art Desinfektion ... aber nicht genug.)
Das sieht gut aus - es sei denn, die erwarteten und tatsächlichen Werte selbst stehen nach der Konvertierung in eine Zeichenfolge in geschweiften Klammern - wofür sie dies tun Size
. Zum Beispiel wird Ihre erste Größe konvertiert in:
{Width=0, Height=0}
Die zweite Formatierungsstufe ist also ungefähr so:
string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
"Message = Failed expected {0} actually is {1}", struct1, struct2);
... und genau das scheitert. Autsch.
In der Tat können wir dies wirklich leicht beweisen, indem wir die Formatierung täuschen, um unsere Parameter für die erwarteten und tatsächlichen Teile zu verwenden:
var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");
Das Ergebnis ist:
Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!
Deutlich kaputt, da wir foo
weder den tatsächlichen Wert erwartet hatten bar
!
Im Grunde ist dies wie ein SQL-Injection-Angriff, aber in dem weniger beängstigenden Kontext von string.Format
.
Als Problemumgehung können Sie verwenden, string.Format
wie von StriplingWarrior vorgeschlagen. Dadurch wird vermieden, dass die zweite Formatierungsstufe für das Ergebnis der Formatierung mit den tatsächlichen / erwarteten Werten ausgeführt wird.
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
, struct1.ToString (), struct2.ToString ())) `?