我有一个班级,检查一周中的当前日期是否为星期三。看起来像这样:
public class Wednesday
{
public string IsWednesday()
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Wednesday)
{
return "It’s Wednesday";
}
else
{
return "It’s not Wednesday";
}
}
}
不用担心返回类型,我知道在此特定示例中返回魔术字符串很不好。我们专注于其目的,而不是实现。
我想用单元测试来涵盖当前工作日为星期三和星期三以外的任何情况。
我是单元测试的新手,我想知道在此示例中最好的解决方案是什么。
现在,我将VS2019与MS Test V2一起使用。我已经测试了这两种情况:
[TestClass]
public class WednesdayTests
{
[TestMethod]
public void IsWednesday_CurrentWeekDayIsWednesday_ReturnsItsWedndesday()
{
if (!(DateTime.Now.DayOfWeek == DayOfWeek.Wednesday))
{
return;
}
// Arrange
Wednesday wednesdayObj = new Wednesday();
// Act
string result = wednesdayObj.IsWednesday();
// Assert
Assert.AreEqual("It’s Wednesday", result);
}
[TestMethod]
public void IsWednesday_CurrentWeekDayIsNotWednesday_ReturnsItsNotWednesday()
{
if (!(DateTime.Now.DayOfWeek != DayOfWeek.Wednesday))
{
return;
}
Wednesday wednesdayObj = new Wednesday();
string result = wednesdayObj.IsWednesday();
Assert.AreEqual("It’s not Wednesday", result);
}
}
在某些情况下(例如我的情况),是否可以退出测试方法?
或者我的解决方案天生有问题吗?
很高兴听到有经验的软件开发人员的任何建议!
P.S。只是注意到,只有在实际上是Wendesday时才进行测试:)哇,这肯定不是解决方案!
我会说在单元测试中使用return;
是不好的做法。
[单元测试的最大好处之一是,它们使更改(读取重构)生产代码成为一个直接的过程……而且我们不希望该过程取决于某人决定在哪个工作日更改代码。 。
如果测试和代码取决于时间,则需要一种方法来控制测试中的时钟。
实际上,这意味着您需要隐藏生产代码取决于可以在测试用例中控制的抽象背后的DateTime.Now
的事实。
单元测试的基本原则之一是,它应该是可重复的且独立的。按原样,您的不是。
使单元可测试方法取决于当前日期的一种方法是为它们提供恒定的“现在”值(测试运行程序提供的值)。
public string IsWednesday() => IsWednesday(DateTime.Now);
public string IsWednesday(DateTime time)
{
if (time.DayOfWeek == DayOfWeek.Wednesday)
{
return "It’s Wednesday";
}
else
{
return "It’s not Wednesday";
}
}
然后,您可以使用固定日期运行测试,涵盖“星期三”和“非星期三”两种情况。这种方法是一般策略的示例:环境在正常执行过程中提供的任何信息(机器名称,日期,区域性等)都应该是被测方法中的参数,并且测试台应该提供一系列有意义的值。
关于实际测试(如果可以,请帮个忙,使用NUnit或XUnit:它们变得微不足道。
[TestMethod]
public void ItsNotWednesday()
{
var wednesdayObj = new Wednesday();
var result = wednesdayObj.IsWednesday(new DateTime(2019, 10, 5)); // Not a wednesday
Assert.AreEqual("It’s not Wednesday", result);
}