我正在用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);
}
但是我敢肯定这不是做我想要的最有效的方法。你有主意吗?
非常感谢。
答案 0 :(得分:0)
您正在比较引用类型,这在您比较内存中的引用时不起作用,并且它们将不相等。您应该重写Equals()函数,然后在测试中使用它。
Equals函数接受一个类型,然后您就可以进行比较,例如,将其添加到Ship类中:
Assert.IsTrue(expectedShip.Equals(resultShip))
然后您只需在测试中执行此操作即可
{{1}}
答案 1 :(得分:0)
在C#中根本不可能完成第一个示例。根据规范,属性必须在其构造函数/属性中采用常量参数,并且禁止执行其他任何操作(因为属性是在编译时以二进制形式烘烤的)。在这种情况下,导致失败的原因是属性中的构造函数调用new Aircraft()
,这是一个非常量表达式(它导致Aircraft
类的构造函数运行),因此无法使用在所有属性中。
作为解决方法,字符串通常是不错的选择。请注意,C#6引入了nameof
运算符以简化该操作并提供一些编译器支持,如下所示:
[DataRow("Aircraft Cruiser", 5, OccupationType.Aircraft, nameof(Aircraft))]
对于方法代码本身,如果您事先知道所有可能性,则switch
是一个选项,但是否则,您需要涉及反射以从类名创建对象。