【问题标题】:NUnit parameterized tests with datetime带有日期时间的 NUnit 参数化测试
【发布时间】:2011-10-30 04:28:08
【问题描述】:

用 NUnit 是不是不可能做到以下几点?

[TestCase(new DateTime(2010,7,8), true)]
public void My Test(DateTime startdate, bool expectedResult)
{
    ...
}

我真的很想在里面放一个datetime,但它似乎不喜欢它。错误是:

属性参数必须是常量表达式,typeof 表达式 或属性参数类型的数组创建表达式

我阅读的一些文档似乎表明您应该能够,但我找不到任何示例。

【问题讨论】:

标签: unit-testing nunit


【解决方案1】:

我可能会使用类似ValueSource 属性的东西来做到这一点:

public class TestData
{
    public DateTime StartDate{ get; set; }
    public bool ExpectedResult{ get; set; }
}

private static TestData[] _testData = new[]{
    new TestData(){StartDate= new DateTime(2010, 7, 8), ExpectedResult= true}};

[Test]
public void TestMethod([ValueSource("_testData")]TestData testData)
{
}

这将为 _testData 集合中的每个条目运行 TestMethod。

【讨论】:

  • 这是一个很好的答案并且效果很好。然而,现在是 2018 年,对于刚刚偶然发现这一点的开发人员,应该注意的是,使用 nameof() 比使用字符串文字更可取。所以你只需要: [ValueSource(nameof(_testData))]TestData testData
【解决方案2】:

您应该使用文档中的 TestCaseData 类:http://www.nunit.org/index.php?p=testCaseSource&r=2.5.9

除了指定一个预期的结果,比如:

 new TestCaseData(12, 4).Returns(3);

您还可以指定预期的异常等:

 new TestCaseData(0, 0)
    .Throws(typeof(DivideByZeroException))
    .SetName("DivideByZero")
    .SetDescription("An exception is expected");

【讨论】:

    【解决方案3】:

    您可以在TestCase 属性中将日期指定为常量字符串,然后在方法签名中将类型指定为DateTime

    NUnit 会自动对传入的字符串执行DateTime.Parse()

    例子:

    [TestCase("01/20/2012")]
    [TestCase("2012-1-20")] // Same case as above in ISO 8601 format
    public void TestDate(DateTime dt)
    {
        Assert.That(dt, Is.EqualTo(new DateTime(2012, 01, 20)));
    }
    

    【讨论】:

    • 这似乎只在使用斜杠时才使用美式格式。如果像我一样,你住在美国以外,你可以使用这种格式“2014-12-25”
    • 这很棒。不过,似乎它不适用于DateTime?!?
    • 迄今为止最简单的解决方案
    • 跟进@Robert Brooker 的评论,“2014-12-25”格式也适用于美国。
    【解决方案4】:

    另一种选择是使用更详细的方法。特别是如果我不一定事先知道,给定的字符串输入会产生什么样的DateTime()(如果有的话......)。

    [TestCase(2015, 2, 23)]
    [TestCase(2015, 12, 3)]
    public void ShouldCheckSomething(int year, int month, int day)
    {
        var theDate = new DateTime(year,month,day);
        ....
    } 
    

    ...注意TestCase 最多支持 3 个参数,因此如果您需要更多参数,请考虑以下内容:

    private readonly object[] testCaseInput =
    {
        new object[] { 2000, 1, 1, true, "first", true },
        new object[] { 2000, 1, 1, false, "second", false }
    }
    
    [Test, TestCaseSource("testCaseInput")]
    public void Should_check_stuff(int y, int m, int d, bool condition, string theString, bool result)
    {
    ....
    }
    

    【讨论】:

      【解决方案5】:

      似乎 NUnit 不允许在 TestCase(s) 中初始化非原始对象。最好使用TestCaseData

      您的测试数据类如下所示:

      public class DateTimeTestData
      {
          public static IEnumerable GetDateTimeTestData()
          {
              // If you want past days.
              yield return new TestCaseData(DateTime.Now.AddDays(-1)).Returns(false);
              // If you want current time.
              yield return new TestCaseData(DateTime.Now).Returns(true);
              // If you want future days.
              yield return new TestCaseData(DateTime.Now.AddDays(1)).Returns(true);
          }
      }
      

      在您的测试课程中,您可以让测试包含一个指向您的测试数据的TestCaseSource

      使用方法:TestCaseSource(typeof(这里是类名), nameof(这里是属性名))

      [Test, TestCaseSource(typeof(DateTimeTestData), nameof(GetDateTimeTestData))]
      public bool GetDateTime_GivenDateTime_ReturnsBoolean()
      {
          // Arrange - Done in your TestCaseSource
      
          // Act
          // Method name goes here.
      
          // Assert
          // You just return the result of the method as this test uses ExpectedResult.
      }
      

      【讨论】:

      • 在你的单元测试中引入像DateTime.Now这样的依赖是不好的。你最好使用存根
      【解决方案6】:

      Nunit 已改进并隐式尝试转换属性参数。 见文档:NUnit3 Doc - see note

      这行得通:

      [TestCase("2021.2.1", ExpectedResult = false)]
      [TestCase("2021.2.26", ExpectedResult = true)]
      public bool IsDate(DateTime date) => date.Date.Equals(new DateTime(2021, 2, 26));
      

      注意对 DateTime 字符串参数使用英语文化格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-16
        • 2011-01-22
        • 2021-02-03
        • 1970-01-01
        相关资源
        最近更新 更多