已生成序列的可读单元测试

本文关键字:单元测试 | 更新日期: 2023-09-27 18:24:14

假设我有一个返回IEnumerable<int>对象的方法。该方法利用yield return关键字生成一个无限序列。Fibonacci算法示例:

public static IEnumerable<long> Fibonacci()
{
    long x = 0L;
    long y = 1L;
    long z;
    yield return x;
    yield return y;
    while (true)
    {
        z = x + y;
        yield return z;
        y = x;
        x = z;
    }
}

如何正确地为这样的序列创建单元测试?我所说的"适当"也是指可读性。

我可以写这样的单元测试:

[TestMethod]
public void FibonacciTest()
{
    var actual = MyClass.Fibonacci();
    var @enum = actual.GetEnumerator();
    Assert.IsTrue(@enum.MoveNext();
    Assert.AreEqual(@enum.Current), 0);
    Assert.IsTrue(@enum.MoveNext();
    Assert.AreEqual(@enum.Current), 1);
    Assert.IsTrue(@enum.MoveNext();
    Assert.AreEqual(@enum.Current), 1);
    Assert.IsTrue(@enum.MoveNext();
    Assert.AreEqual(@enum.Current), 2);
    Assert.IsTrue(@enum.MoveNext();
    Assert.AreEqual(@enum.Current), 3);
    Assert.IsTrue(@enum.MoveNext();
    Assert.AreEqual(@enum.Current), 5);
    Assert.IsTrue(@enum.MoveNext();
}

这个测试有效,但我认为它不可读。编写序列单元测试的一般准则是什么(斐波那契算法只是一个例子)?

附言:我使用的是Visual Studio OOB测试套件+Pex。

已生成序列的可读单元测试

像这样的东西怎么样

[TestMethod]
public void FibonacciFirstSixTest()
{
    var actual = MyClass.Fibonacci();
    int[] expected = { 0, 1, 1, 2, 3, 5 };
    Assert.IsTrue(actual.Take(6).SequenceEqual(expected));
}

顺便说一句,我想指出的是,你并没有真的有一个无限序列,因为Fibonacci序列中只有这么多成员可以放入long(或任何固定大小的数据类型)。你不妨测试一下全部92个。

CollectionAssert.AreEqual(new[] {0,1,1,2,3,5}, MyClass.Fibonacci().Take(6).ToList());