Я разрабатываю игру про боевой корабль в ASP.NET, и у меня возникла проблема с моими модульными тестами с MSTest.
Я хочу протестировать создание каждого типа лодки и убедиться, что конструктор каждой лодки создает желаемую лодку с подходящей шириной и т. д. Итак, я решил написать общий метод с тегом [DataTestMethod]. Но я не понимаю, как я могу использовать объект в качестве параметра.
Вот пример того, что я хочу:
[DataTestMethod]
[DataRow("Aircraft Cruiser", 5, OccupationType.Aircraft, new Aircraft())]
public void CreateAircraft(string description, int width, OccupationType occupationType, Ship resultShip)
{
var expectedShip = new Ship
{
Description = description,
Width = width,
OccupationType = occupationType
};
Assert.AreEqual(expectedShip, resultShip)
}
Но это явно не работает. Я сделал что-то вроде этого:
[DataTestMethod]
[DataRow("Aircraft Cruiser", 5, OccupationType.Aircraft, "Aircraft")]
public void CreateAircraft(string description, int width, OccupationType occupationType, string shipType)
{
var expectedShip = new Ship
{
Description = description,
Width = width,
OccupationType = occupationType
};
Ship resultShip = null;
switch (shipType)
{
case "Aircraft":
resultShip = new Aircraft();
break;
}
Assert.AreEqual(expectedShip, resultShip);
}
но я уверен, что это не самый эффективный способ делать то, что я хочу. Есть идеи?
Большое спасибо.
Вы сравниваете ссылочные типы, это не работает, поскольку вы сравниваете ссылку в памяти, и они не будут равны. Вы должны переопределить функцию Equals (), а затем использовать ее в своих тестах.
Функция Equals принимает тип, а затем вы просто выполняете сравнения, например, добавляете это в свой класс Ship:
public override bool Equals(Ship obj)
{
if (this.Width != obj.Width)
{
return false;
}
return true;
}
Затем вы просто делаете это в своих тестах:
Assert.IsTrue(expectedShip.Equals(resultShip))
Первый пример просто невозможно сделать на C#. Согласно спецификации, атрибуты должны принимать постоянные параметры в своем конструкторе / свойствах, а все остальное запрещено (поскольку атрибуты запекаются в двоичном файле во время компиляции). В этом случае причиной сбоя является вызов конструктора new Aircraft()
в атрибуте, который является непостоянным выражением (вызывает запуск конструктора класса Aircraft
), поэтому его нельзя использовать в атрибутах вообще.
В качестве обходного пути обычно хорошим кандидатом является строка. Обратите внимание, что C# 6 вводит оператор nameof
, чтобы упростить это и обеспечить некоторую поддержку компилятора, например:
[DataRow("Aircraft Cruiser", 5, OccupationType.Aircraft, nameof(Aircraft))]
Что касается самого кода метода, switch
- это вариант, если вы заранее знаете все возможности, но в противном случае вам нужно задействовать отражение для создания объекта из имени класса.
Нет. Assert.AreEqual использует метод Equals объекта. Assert.AreSame проверить ссылку.