1

I've just started to learn testing, and have following problem.My method takes IEnumerable<int> parameter and returns same.Basically, it is method for merging two sorted arrays/lists but since I'm reading values from files, I don't want to use unnecessary memory for creating list or array so I have decided to use IEnumerable. I have one method which reads file and converts all the numbers that finds in file into integers and returns IEnumerable<int>. So the following method use that result and merge those sorted integers.

public static IEnumerable<int> GetSortedIntegers(IEnumerable<int> first , IEnumerable<int> second)
{
    var item1 = first.GetEnumerator();
    var item2 = second.GetEnumerator();

    bool item1HasNext = item1.MoveNext();
    bool item2HasNext = item2.MoveNext();

    while (item1HasNext && item2HasNext)
    {
        if (item1.Current > item2.Current)
        {
            yield return item2.Current;
            item2HasNext = item2.MoveNext();
        }
        else if(item1.Current == item2.Current)
        {
            yield return item2.Current;
            item2HasNext = item2.MoveNext();
            item1HasNext = item1.MoveNext();
        }
        else
        {
            yield return item1.Current;
            item1HasNext = item1.MoveNext();
        }
    }
    while (item1.MoveNext())
    {
        yield return item1.Current;
    }
    while (item2.MoveNext())
    {
        yield return item2.Current;
    }
}

I want to test functionality of this method and create test cases using Nunit, but I don't know what collection should I create for testing purpose.Idea is to do something like following :

[Test]
public static void GetSortedIntegersTest()
{           
    var first = new List<int>() { 0 };
    var second = new List<int>() { 1, 2 };

    var expected = new List<int>{ 0, 1, 2 };
    var actual = GetSortedIntegers(first, second);
    CollectionAssert.AreEqual(expected, actual);
}

Thank you for Your advice.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Hank Mooody
  • 527
  • 11
  • 29
  • Why are you concerned about memory usage? Just create something that implements `IEnumerable`. You can't construct an interface, you have to use a specific implementation. – Daniel Mann Jun 12 '16 at 18:17
  • Am I getting this right, you are suggesting that I need to create some collection which implements IEnumerable, than create 3 instance of that collection, first two populate with values and pass them as parameters to my method and third one populate with expected result ? thank you – Hank Mooody Jun 12 '16 at 18:29
  • That's what you've already done in the test you show, which looks fine as a single test. It's not clear what your question is. – Charlie Jun 12 '16 at 20:48
  • `CollectionAssert` works with `ICollection` so you should convert the `actual` to a list. – Nkosi Jun 12 '16 at 20:50

2 Answers2

2

If you want to determine whether two sequences contain the same elements in the same order, call Enumerable.SequenceEqual. There's no need to convert the return sequence from the merge to a concrete collection.

So:

var expected = new List<int>{0, 1, 2};
var actual = GetSortedIntegers(first, second);
Assert.IsTrue(expected.SequenceEqual(actual));
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
0

CollectionAssert works with ICollection so you should convert the actual to a list.

[Test]
public static void GetSortedIntegersTest()
{           
    var first = new List<int>() { 0 };
    var second = new List<int>() { 1, 2 };

    var expected = new List<int>{ 0, 1, 2 };
    var actual = GetSortedIntegers(first, second);
    CollectionAssert.AreEqual(expected, actual.ToList());
}

You current test will fail but its a start of RGR. now you can refactor and retest till you get Green.

You can look at this Q&A Is there an easy way to merge two ordered sequences using LINQ?

Community
  • 1
  • 1
Nkosi
  • 235,767
  • 35
  • 427
  • 472