根据实时值进行或退出单元测试的正确方法
Proper way to conduct or quit a unit test based on a real-time value
我有一个 class 检查当前星期几是否是星期三。它看起来像这样:
public class Wednesday
{
public string IsWednesday()
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Wednesday)
{
return "It’s Wednesday";
}
else
{
return "It’s not Wednesday";
}
}
}
不用担心 return 类型,我知道在这个特定示例中 return 一个魔术字符串是不好的。我们专注于它的目的,而不是实施。
对于当前工作日是星期三和除星期三以外的任何情况,我都愿意用单元测试来覆盖它。
我是单元测试的新手,我想知道这个例子中最好的解决方案是什么。
现在,我正在使用 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);
}
}
当某些条件不满足时,return 退出测试方法是否被认为是可以的,就像我的情况一样?
或者我的解决方案存在固有问题?
很高兴听到经验丰富的软件开发人员的任何建议!
P.S。刚注意到只有在星期三才会进行测试:)哇,这肯定不是解决方案!
我会说在单元测试中使用 return;
是不好的做法。
单元测试的最大好处之一是它们使更改(阅读重构)生产代码成为一个直接的过程……我们不希望该过程取决于某人决定更改的工作日上代码。
如果您的测试和代码依赖于时间,您需要一种方法来控制测试中的时钟。
在实践中,这意味着您需要隐藏生产代码依赖于 DateTime.Now
的事实,您可以在测试用例中控制抽象。
单元测试的基本原则之一是它应该是可重复的和独立的。
你的,原样,不是。
根据当前日期制作可单元测试方法的一种方法是为它们提供常量 "now" 值(由测试 运行ner 提供的值)。
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";
}
}
然后你可以运行固定日期的测试,涵盖"wednesday"和"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);
}
我有一个 class 检查当前星期几是否是星期三。它看起来像这样:
public class Wednesday
{
public string IsWednesday()
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Wednesday)
{
return "It’s Wednesday";
}
else
{
return "It’s not Wednesday";
}
}
}
不用担心 return 类型,我知道在这个特定示例中 return 一个魔术字符串是不好的。我们专注于它的目的,而不是实施。
对于当前工作日是星期三和除星期三以外的任何情况,我都愿意用单元测试来覆盖它。
我是单元测试的新手,我想知道这个例子中最好的解决方案是什么。
现在,我正在使用 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);
}
}
当某些条件不满足时,return 退出测试方法是否被认为是可以的,就像我的情况一样?
或者我的解决方案存在固有问题?
很高兴听到经验丰富的软件开发人员的任何建议!
P.S。刚注意到只有在星期三才会进行测试:)哇,这肯定不是解决方案!
我会说在单元测试中使用 return;
是不好的做法。
单元测试的最大好处之一是它们使更改(阅读重构)生产代码成为一个直接的过程……我们不希望该过程取决于某人决定更改的工作日上代码。
如果您的测试和代码依赖于时间,您需要一种方法来控制测试中的时钟。
在实践中,这意味着您需要隐藏生产代码依赖于 DateTime.Now
的事实,您可以在测试用例中控制抽象。
单元测试的基本原则之一是它应该是可重复的和独立的。 你的,原样,不是。
根据当前日期制作可单元测试方法的一种方法是为它们提供常量 "now" 值(由测试 运行ner 提供的值)。
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";
}
}
然后你可以运行固定日期的测试,涵盖"wednesday"和"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);
}