Aku memahaminya. Dan ya, itu bug.
Masalahnya adalah ada dua tingkat yang string.Format
terjadi di sini.
Itu pertama tingkat format adalah sesuatu seperti:
string template = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
expected, actual, message);
Kemudian kami menggunakan string.Format
dengan parameter yang Anda berikan:
string finalMessage = string.Format(template, parameters);
(Jelas ada budaya yang disediakan, dan beberapa jenis sanitasi ... tapi tidak cukup.)
Kelihatannya baik-baik saja - kecuali nilai yang diharapkan dan nilai aktual itu sendiri diakhiri dengan tanda kurung di, setelah diubah menjadi string - yang mereka lakukan Size
. Misalnya, ukuran pertama Anda akhirnya diubah menjadi:
{Width=0, Height=0}
Jadi level kedua dari pemformatan adalah seperti:
string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
"Message = Failed expected {0} actually is {1}", struct1, struct2);
... dan itulah yang gagal. Aduh.
Memang, kami dapat membuktikan ini dengan sangat mudah dengan menipu pemformatan untuk menggunakan parameter kami untuk bagian yang diharapkan dan aktual:
var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");
Hasilnya adalah:
Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!
Jelas rusak, seperti yang tidak kami duga foo
dan bukan nilai sebenarnya bar
!
Pada dasarnya ini seperti serangan injeksi SQL, tetapi dalam konteks yang agak kurang menakutkan string.Format
.
Sebagai solusinya, Anda dapat menggunakan string.Format
seperti yang disarankan StriplingWarrior. Itu menghindari tingkat kedua pemformatan dilakukan pada hasil pemformatan dengan nilai aktual / yang diharapkan.
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
sudahkah Anda mencoba memiliki , struct1.ToString (), struct2.ToString ())) `?