问题
Let's suppose I have some method that returns a IEnumerable<int>
object. This methods make use of yield return
keyword to produce a infinite sequence. Example of the Fibonacci algorithm :
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;
}
}
How can I properly create unit test for such sequence ? By proper I also mean readable.
I can write unit tests like this :
[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();
}
This test works, but I don't think it is readable. What are general (Fibonacci alogrithm was only a example) guidelines for writing unit tests for sequences ?
PS: I'm using Visual Studio OOB Test suite + Pex.
回答1:
var expectedFibSequence = new[] {0,1,1,2,3,5};
CollectionAssert.AreEqual(
expected,
MyClass.Fibonacci().Take(expected.Length).ToList());
回答2:
How about something like:
[TestMethod]
public void FibonacciFirstSixTest()
{
var actual = MyClass.Fibonacci();
int[] expected = { 0, 1, 1, 2, 3, 5 };
Assert.IsTrue(actual.Take(6).SequenceEqual(expected));
}
By the way, I would point out that you don't really have an infinite sequence there since there are only so many members of the Fibonacci series that can fit in long
(or any fixed-size data-type for that matter). You might as well test all 92 of them.
来源:https://stackoverflow.com/questions/9263479/readable-unit-testing-of-a-yielded-sequence