Jamie Dixon
Jamie Dixon

Reputation: 53991

How do I mock an IEnumerable<T> so that I can test a method that receives it

I have a method that I want to test which expects an IEnumerable<T> as a parameter.

I'm currently mocking the contents of the IEnumerable<T> as follows (Using Moq):

 var mockParent = new Mock<ICsvTreeGridExportable>();
 var mockChild = new Mock<ICsvTreeGridExportable>();

How do it put these mocked objects inside an IEnumerable<T> so that I can pass them as a parameter to the method I want to test?

The method I'm testing expects to receive an IEnumerable<ICsvTreeGridExportable>

Upvotes: 15

Views: 11115

Answers (5)

Dan Tao
Dan Tao

Reputation: 128317

Here's an alternative to sebastian's answer that allows you to specify how many dummies of any type you want:

private IEnumerable<T> GetDummies<T>(int numDummies) where T : new() {
    for (int i = 0; i < numDummies; i++) yield return new T();
    yield break;
}

Or (if you want to use be able to use types without empty constructors):

private IEnumerable<T> GetDummies<T>(Func<T> generator, int numDummies) {
    for (int i = 0; i < numDummies; i++) yield return generator.Invoke();
    yield break;
}

Upvotes: 0

Noldorin
Noldorin

Reputation: 147270

I would just create an array using the collection intialiser syntax. i.e.

var mockParent = new Mock<ICsvTreeGridExportable>();
var mockChild = new Mock<ICsvTreeGridExportable>();

TestMethod(new[] { mockParent.Object, mockChild.Object });

Arrays in .NET implement the IEnumerable<T> interface, so you're all set.

Note: If you want a "pure" IEnumerable<T> (as Luke points out), you could use a little bit of LINQ to do that:

TestMethod((new[] { mockParent.Object, mockChild.Object }).TakeWhile(true));

Upvotes: 20

LukeH
LukeH

Reputation: 269348

You could just create an array. (Arrays implement the IEnumerable<T> interface.)

var mockEnumerable = new[] { mockParent.Object, mockChild.Object };

If you want a "pure" IEnumerable<T> that can't be cast back to an array etc, then you could create it using a helper method:

var mockEnumerable = CreateEnumerable(mockParent.Object, mockChild.Object);

// ...

public static IEnumerable<T> CreateEnumerable<T>(params T[] items)
{
    foreach (T item in items)
    {
        yield return item;
    }
}

(As Jamie mentions in the comments, you need to use the mocked objects, not the Mock objects. For example, mockParent.Object, mockChild.Object etc, not just mockParent or mockChild.)

Upvotes: 6

Josh Pearce
Josh Pearce

Reputation: 3455

List<ICsvTreeGridExportable> myList = new List<ICsvTreeGridExportable>();
myList.Add(mockParent);
myList.Add(mockChild);
return myList;

Upvotes: 0

sebagomez
sebagomez

Reputation: 9599

You could make something like this:
Create a function Dummy

private IEnumerable<ICsvTreeGridExportable> Dummy()
{
     yield return new ICsvTreeGridExportable();
}

And in your test function do something like

private void TestFunction()
{
   ThisIsTheOneThatNeedsIenumerable(Dummy());
}

hope it helps

Upvotes: 1

Related Questions