Я пытаюсь подтвердить равенство двух System.Drawing.Size
структур и получаю исключение формата вместо ожидаемого сбоя утверждения.
[TestMethod]
public void AssertStructs()
{
var struct1 = new Size(0, 0);
var struct2 = new Size(1, 1);
//This throws a format exception, "System.FormatException: Input string was not in a correct format."
Assert.AreEqual(struct1, struct2, "Failed. Expected {0}, actually it is {1}", struct1, struct2);
//This assert fails properly, "Failed. Expected {Width=0, Height=0}, actually it is {Width=1, Height=1}".
Assert.AreEqual(struct1, struct2, "Failed. Expected " + struct1 + ", actually it is " + struct2);
}
Это предполагаемое поведение? Я что-то здесь делаю не так?
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
, struct1.ToString (), struct2.ToString ())) `?Ответы:
Я понял. И да, это баг.
Проблема в том, что здесь происходит два уровня
string.Format
.Первый уровень форматирования что - то вроде:
Затем мы используем
string.Format
с указанными вами параметрами:(Очевидно, есть культура и какая- то санитарная обработка ... но этого недостаточно.)
Это выглядит нормально - если только ожидаемые и фактические значения сами по себе не заключаются в фигурные скобки после преобразования в строку, для чего они и используются
Size
. Например, ваш первый размер будет преобразован в:Итак, второй уровень форматирования выглядит примерно так:
... и вот что не получается. Ой.
Действительно, мы можем очень легко доказать это, обманув форматирование, чтобы использовать наши параметры для ожидаемой и фактической частей:
Результат:
Явно сломан, как мы и не ожидали, и
foo
не было реальной стоимостиbar
!В основном это похоже на атаку с использованием SQL-инъекций, но в менее пугающем контексте
string.Format
.В качестве обходного пути вы можете использовать,
string.Format
как предлагает StriplingWarrior. Это позволяет избежать выполнения второго уровня форматирования результата форматирования с использованием фактических / ожидаемых значений.источник
%*n
эквивалента? :(Я думаю, вы нашли ошибку.
Это работает (выдает исключение assert):
И это работает (выводит сообщение):
Но это не работает (бросает
FormatException
):Я не могу придумать ни одной причины, по которой такое поведение можно было бы ожидать. Я бы отправил отчет об ошибке. А пока вот обходной путь:
источник
Я согласен с @StriplingWarrior, что это действительно похоже на ошибку метода Assert.AreEqual () как минимум при двух перегрузках. Как уже указывал StiplingWarrior, следующее не работает;
Я немного поэкспериментировал с этим, чтобы быть более явным в использовании кода. Следующее тоже не работает;
И
Это заставило меня задуматься. System.Drawing.Size - это структура. А как насчет предметов? Список параметров действительно указывает, что список после
string
сообщенияparams object[]
. Технически структуры yes - это объекты ... но особые виды объектов, то есть типы значений. Я думаю, в этом и заключается ошибка. Если мы используем наш собственный объект с подобным использованием и структурами наSize
следующем фактически делает работу;источник
class
илиstruct
, а в том,ToString
содержит ли значение фигурные скобки, которые выглядят какString.Format
.Я считаю, что первое утверждение неверно.
Используйте вместо этого:
источник