2009-11-13 10 views
15

Tengo un método que quiero probar que espera un IEnumerable<T> como parámetro.¿Cómo me burlo de un IEnumerable <T> para poder probar un método que lo reciba?

Actualmente estoy burlando el contenido de la IEnumerable<T> de la siguiente manera (Usando Moq):

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

Cómo hacer es poner estos objetos se burlaban dentro de un IEnumerable<T> para que pueda pasar a ellos como un parámetro para el método Quiero probar?

El método Estoy probando espera recibir un IEnumerable<ICsvTreeGridExportable>

Respuesta

20

me acaba de crear una matriz usando la sintaxis colección intialiser. es decir

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

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

matrices en .NET implementan la interfaz IEnumerable<T>, por lo que ya está todo listo.

Nota: Si desea un "puro" IEnumerable<T> (como se señala Lucas), podría utilizar un poco de LINQ para hacer eso:

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

yap ... mucho más simple que mi solución (+1) – sebagomez

+0

Noldorin, si puede cambiar su respuesta para tener mockParent.Object y mockChild.Object, entonces puedo marcar esto como la respuesta correcta. La respuesta de Lukes a continuación también fue extremadamente útil.Lástima que no puedo marcar ambos como aceptados :) –

+0

@Jamie: Listo. :) – Noldorin

6

Se podía crear una matriz. (. Las matrices implementan la interfaz IEnumerable<T>)

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

Si desea un "puro" IEnumerable<T> que no se puede convertir de nuevo a una matriz, etc, entonces se podría crear utilizando un método de ayuda:

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

// ... 

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

(Jamie Como se menciona en los comentarios, es necesario utilizar los burlado de los objetos, no los Mock objetos. Por ejemplo, mockParent.Object, mockChild.Object etc, no simplemente mockParent o mockChild)

+0

Gracias Luke. Cuando intento pasar my mockEnumerable al método, aparece el siguiente error: Argument.Type 'Moq.Mock [] no se puede asignar al tipo de parámetro IEnumerable . ¿Qué debo hacer para asegurarme de que mis objetos simulados son del tipo correcto? –

+0

El método 'CreateEnumerable' es exactamente lo que inicialmente consideré, pero realmente no tiene ninguna ventaja sobre una matriz. El compilador genera una clase ficticia de todos modos, entonces meh. Sin embargo, si desea una inicialización lenta (vea la respuesta de Sebastián), podría ser útil. – Noldorin

+0

Esto todavía me da el mismo problema. Cuando utilicé IEnumerable x = CreateEnumerable (mockParent, mockChild); Todavía estoy informado de que "No se puede convertir el tipo de fuente". Uno es del tipo IEnum ... y el otro de tipo IEnum ... . Me estoy perdiendo algo muy simple aquí. –

1

usted podría hacer algo como esto:.
crear una función simulada

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

Y en su función de prueba de hacer algo como

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

espero que ayude

+0

Creo que quiere tener un 'IEnumerable' de más de un elemento. – Noldorin

+0

sí, con el retorno de rendimiento puede devolver tantos como quiera ... Me olvidé de eso ... – sebagomez

+1

@sebastian: De hecho. Sin embargo, este método podría ser útil si desea una "inicialización diferida", es decir, solo cree el objeto cuando sea necesario. – Noldorin

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

Aquí es una alternativa a la respuesta de Sebastián que le permite especificar el número de maniquíes de cualquier tipo que desee:

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

O (si desea utilizar será capaz de utilizar los tipos sin constructores vacío):

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