2
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.ThatAssume.That[Theory]
  2. 这种情况确实更适合 a[Theory]而不是 a[Test]吗?
4

1 回答 1

1

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

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

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

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

用,代替?[Theory]被认为是错误的或不好的风格?Assert.ThatAssume.That

不,它只是另一个要使用的工具,而且不比Assert.That.

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

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

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

测试 if a * bis even 只有在满足前提条件后才有意义。如果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) { … }
于 2013-05-10T20:02:10.200 回答