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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With