English 中文(简体)
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>

最佳回答

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));
问题回答

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.)

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

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

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;
}




相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签