Ben hallederim. Ve evet, bu bir böcek.
Sorun şu ki string.Format
, burada devam etmenin iki seviyesi var.
İlk biçimlendirme düzeyi gibi bir şey:
string template = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
expected, actual, message);
Ardından string.Format
, sağladığınız parametrelerle birlikte kullanırız:
string finalMessage = string.Format(template, parameters);
(Belli ki sağlanan kültürler ve bir çeşit temizlik var ... ama yeterli değil.)
Bu iyi görünüyor - beklenen ve gerçek değerlerin kendileri bir dizeye dönüştürüldükten sonra küme ayraçları ile bitmedikçe - bunun için yapıyorlar Size
. Örneğin, ilk boyutunuz şu şekilde dönüştürülür:
{Width=0, Height=0}
Dolayısıyla, ikinci düzey biçimlendirme şuna benzer:
string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
"Message = Failed expected {0} actually is {1}", struct1, struct2);
... ve başarısız olan da bu. Ah.
Aslında, biçimlendirmeyi parametrelerimizi beklenen ve gerçek parçalar için kullanacak şekilde kandırarak bunu gerçekten kolayca kanıtlayabiliriz:
var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");
Sonuç:
Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!
Açıkça kırıldı, çünkü beklemiyorduk foo
ve gerçek değer değildi bar
!
Temelde bu bir SQL enjeksiyon saldırısı gibidir, ancak daha az korkutucu bağlamda string.Format
.
Geçici bir çözüm olarak, string.Format
StriplingWarrior'ın önerdiği gibi kullanabilirsiniz . Bu, gerçek / beklenen değerlerle biçimlendirme sonucunda ikinci düzey biçimlendirmenin gerçekleştirilmesini önler.
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
struct1.ToString (), struct2.ToString ())) `` sahip olmayı denediniz mi?