所以我是单位测试的新手(很晚才到派对,但我至少在这里)。我将几个ASP.NET MVC Web应用程序使用的一些常用代码提取到一个或多个类库中。我现在正在为一些代码编写单元测试......其中大部分实际上是IDataReader上的扩展方法(意图用于对抗OdbcDataReader)。在下面的代码中,扩展方法扩展了对象,因此我可以实际编写单元测试。我曾尝试使用Moq来模拟IDataReader来测试扩展方法,但我已经读过,这是不可能的。在任何情况下,这不是真正的问题所在。
这是我的问题。我有一个名为" GetSafeDecimal"的方法。意图是它将被用作:
dr.getSafeDecimal(dr["FieldValue"])
该方法定义如下:
public static decimal GetSafeDecimal(this object rdr, object value)
{
decimal result = 0;
decimal temp = -1;
if (value == null || value is DBNull)
result = 0;
else if (decimal.TryParse(value.ToString(), out temp))
result = temp;
else if (value is string)
{
String s = Convert.ToString(value) ?? string.Empty;
s = s.Replace(" ", "");
if (String.IsNullOrEmpty(s) ||
!decimal.TryParse(s, out temp))
{
result = 0;
}
else
{
result = decimal.Parse(s);
}
}
return result;
}
我的实际问题:我在单元测试中看到了大量的重复。设置并不难。我只是为我测试的每个输入写一个单元测试。这是"正确"单元测试的方法?
以下是我对上述方法的一些单元测试:
[TestMethod]
public void GetSafeDecimalNullReturns0()
{
decimal result = "".GetSafeDecimal(null);
Assert.AreEqual(result , 0);
}
[TestMethod]
public void GetSafeDecimalIntReturnsDecimalValue()
{
decimal result = "".GetSafeDecimal(5);
Assert.AreEqual(result, 5);
}
[TestMethod]
public void GetSafeDecimalStringReturns0()
{
decimal result = "".GetSafeDecimal("asdf");
Assert.AreEqual(result, 0);
}
[TestMethod]
public void GetSafeDecimalStringSpecialCharactersReturns0()
{
decimal result = "".GetSafeDecimal("a_ s)@#$df");
Assert.AreEqual(result, 0);
}
[TestMethod]
public void GetSafeDecimalIntStringReturns0()
{
decimal result = "".GetSafeDecimal("2 3 5");
Assert.AreEqual(result, 235);
}
[TestMethod]
public void GetSafeDecimalDecimalReturnsDecimal()
{
decimal result = "".GetSafeDecimal(3.14M);
Assert.AreEqual(result, 3.14M);
}
[TestMethod]
public void GetSafeDecimalDoubleReturnsDecimal()
{
decimal result = "".GetSafeDecimal(3.14d);
Assert.AreEqual(result, 3.14M);
}
@塞巴斯蒂安的解决方案现场点亮了。切换到nunit后,我的测试现在看起来像:
public class SafeDecimalTestData
{
public static IEnumerable TestCases
{
get
{
yield return new TestCaseData(null).Returns(0);
yield return new TestCaseData(5).Returns(5);
yield return new TestCaseData("asdf").Returns(0);
yield return new TestCaseData("a_ s)@#$df").Returns(0);
yield return new TestCaseData("2 3 5").Returns(235);
yield return new TestCaseData(3.14m).Returns(3.14m);
yield return new TestCaseData(3.14m).Returns(3.14d);
yield return new TestCaseData(new DateTime(2015,1,1)).Returns(0);
}
}
}
[Test, TestCaseSource(typeof(SafeDecimalTestData), "TestCases")]
public decimal GetSafeDecimalTestInputs(object input)
{
return "".GetSafeDecimal(input);
}
我以这种方式编写测试而不是仅使用TestCase属性,因为测试不允许我使用3.14d,3.14m或DateTime等值。我想要一个解决方案,无论我测试的数据类型如何,我都可以对所有测试使用。该解决方案来自NUnit文档: