使用Assert.That(而不是Assume.That)和[Theory]是不对的?

时间:2013-05-10 15:05:45

标签: c# unit-testing nunit theory

interface IPoint
{
    int X { get; }
    int Y { get; }
}

static bool CoincidesWith(this IPoint self, IPoint other); // implementation unknown

我想编写一个NUnit测试来验证我对CoincidesWith含义的假设:

  

self.CoincidesWith(other)⇔(self.X = other.X)∧(self.Y = other.Y

以下是迄今为止我能够提出的最简洁的测试:

[Theory]
void CoincidesWith_Iff_CoordinatesAreEqual(IPoint self, IPoint other)
{
    bool coordinatesAreEqual = (self.X == other.X && self.Y == other.Y);
    Assert.That(self.CoincidesWith(other) == coordinatesAreEqual);
}

我的问题按重要性降序排列:

  1. 使用[Theory],使用Assert.That代替Assume.That时,它被认为是错误的还是糟糕的风格? (The documentation seems to suggest that the latter should be used in conjunction with [Theory].
  2. 这种情况确实更适合[Theory]而不是[Test]

1 个答案:

答案 0 :(得分:1)

经过一番思考后,我得出的结论是,我的上述解决方案没有任何问题。

  

这种情况确实更适合[Theory]而不是[Test]吗?

如果CoincidesWith方法的实现可用于检查(例如作为源代码),或者至少有详细记录,那么就没有必要做出假设 - 我可以简单地查找我需要的内容知道。在这种情况下,[Test] - 或xUnit.net调用测试[Fact] - 似乎更合适。

但由于我无法访问CoincidesWith的实现,并且文档不足,我确实需要对该方法的一般工作做出一些假设,或[Theory]

  

使用[Theory]时,使用Assert.That代替Assume.That会被认为是错误的还是错误的风格?

没有。它只是另一种使用的工具,既不比Assert.That更少也不合适。

[Theory]的上下文中,Assume.That似乎是对所提供的[Datapoints]施加额外约束的正确方法,同时验证实际假设(使用这些数据点)它过去Assume.That)留给Assert.That

一个例子可以说明这一点。让我们试着为这个假设写一个测试:

  

给定偶数整数a和奇数整数b,它们的乘积a * b是偶数。

一旦满足前提条件,测试a * b是否只有意义才有意义。如果a不是偶数,或b不是奇数,则测试既不会成功也不会失败;它应该是不确定的。这正是Assume.That帮助实现的目标。但是,实际测试留给Assert.That

[Theory]
void GivenAnEvenIntegerAndAnOddInteger_ProductIsAnEvenInteger(int a, int b)
{
    Assume.That(a.IsEven());
    Assume.That(b.IsOdd());
    // note: the type system already ensures that `a` and `b` are integers.
    int product = a * b;
    Assert.That(product.IsEven());
    // note: the theory doesn't require `product` to be an integer, so even
    // if the type system didn't already assert this, we would not test for it.
}

[Datapoints]
int[] integers = { 1, 2, 3, 4, 5, 6, 7 };

static bool IsEven(this int integer) { … }
static bool IsOdd(this int integer) { … }