6

您将如何测试与时间相关的方法?

一个简单的例子可能是:

public static int GetAge(DateTime birthdate)
{
    // ...
}

[TestMethod]
public void GetAgeTest()
{
    // This is only ok for year 2013 !
    Assert.AreEqual(GetAge(new DateTime(2000, 1, 1)), 13);
}

问题是它仅适用于当年(在这种情况下为 2013 年)。新的一年一开始,我就必须重写所有时间相关的测试......

单元测试这种方法的最佳方法是什么?

4

7 回答 7

4

您可以覆盖您的GetAge方法查找今天日期的机制。

如果包装DateTime在另一个类中,则可以用在单元测试时返回已知值的假调用替换实际调用。

您可以使用依赖注入在生产的真实实现和测试的假实现之间切换。

于 2013-07-03T13:14:36.057 回答
3

另外,不要忘记“预期”参数是AreEquals.

[TestMethod]
public void GetAgeTest()
{
    int age = 13;
    Assert.AreEqual(age, GetAge(DateTime.Now.AddYears(age * -1));
}

最好将测试拆分为 Arrange - Act - Assert 组,如下所示:

[TestMethod]
public void GetAgeTest()
{
    // Arrange
    int age = 13;

    // Act
    int result = GetAge(DateTime.Now.AddYears(age * -1);

    // Assert
    Assert.AreEqual(age, result);
}
于 2013-07-03T13:15:10.943 回答
2

两个主要选项:

  1. 创建一个隔离时间相关功能的服务,并将其接口注入到需要它的类中。然后您可以模拟此接口以获得测试所需的行为。

  2. 使用像Moles这样的迂回测试框架(也有一些其他的),它可以重新路由静态方法调用,如DateTime.Now.

于 2013-07-03T13:14:07.197 回答
1

像这样的东西可以解决问题

var birthDate = new DateTime(DateTime.Now.Year - 13, 1, 1)
int age = GetAge(birthDate);
Assert.AreEqual(age, 13);
于 2013-07-03T13:14:50.113 回答
1

另一种解决方案是使用 Microsoft Shimes and Fakes。看看http://msdn.microsoft.com/en-us/library/hh549175.aspx

using (ShimsContext.Create())
{
    // Shim DateTime.Now to return a fixed date:
    System.Fakes.ShimDateTime.NowGet = () =>
    { 
        return new DateTime(fixedYear, 1, 1); 
    };
}
于 2013-12-05T19:31:54.110 回答
0

在这种特定情况下可能不是最佳选择,但您也可以将函数的接口扩展为也需要DateTime now传递 a 。

public static int GetAge(DateTime birthdate, DateTime now)
{
    // ...
}

[TestMethod]
public void GetAgeTest()
{
    Assert.AreEqual(GetAge(new DateTime(2000, 1, 1), new DateTime(2013, 1, 1)), 13);
}

您基本上是将获取当前日期的责任委托给调用者(尽管也将单元测试问题推到了那里)。

一个很好的副作用是您在此函数的范围内确实获得了一个明确定义的“现在”。在刻度级别上,调用 DateTime.Now 的那一刻会有所作为。您可以在抽象级别上将函数描述为“给定这个生日和这个当前日期,年龄是”。

同样,这可能不是在每种情况下都最好的方法,但我认为在某些情况下值得考虑。

于 2014-11-14T15:49:08.910 回答
0

另一种解决方案是使用 VirtualTime。,它简化了依赖于时间的应用程序的单元测试,请在此处查看如何使用和示例单元测试:DateTime.Now

于 2018-06-18T01:43:12.673 回答