2010-05-26 22 views
18

Tengo problemas para averiguar cómo configurar indexers en C# con Moq. La documentación Moq es débil, y he hecho un montón de búsqueda ... lo que me gustaría hacer es similar en la solución a How to Moq Setting an Indexed property:Usando Moq para configurar indexadores en C#

var someClass = new Mock<ISomeClass>(); 
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25); 

Quiero modificar lo anterior a trabajar para cualquier índice y cualquier valor por lo que puedo hacer algo como esto:

someClass.Object.SomeIndexedProperty[1] = 5; 

Actualmente tengo el siguiente, que funciona muy bien para la propiedad de captador indexado, pero si alguna vez establecer el valor Moq lo ignora:

var someValues = new int[] { 10, 20, 30, 40 }; 
var someClass = new Mock<ISomeClass>(); 
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()]) 
    .Returns<int>(index => someValues[index]); 

// Moq doesn't set the value below, so the Assert fails! 
someClass.Object.SomeIndexedProperty[3] = 25; 
Assert.AreEqual(25, someClass.Object.SomeIndexedProperty[3]); 
+0

¿Cuál es la variable de índice? ¿De dónde viene? – Grzenio

+0

Soy nuevo en Moq, así que tal vez estoy haciendo algo mal ... pero pensé que el parámetro de índice en la lambda de devoluciones estaba siendo proporcionado por el It.IsAny () expresión en la configuración lambda. –

+0

Tampoco soy un experto (estoy usando RhinoMocks). ¿SomeClass.Object.SomeIndexedProperty [3] devuelve 40? – Grzenio

Respuesta

11

he encontrado una solución a mi problema. Requiere un cambio en mi forma de pensar ... He estado buscando utilizar el Assert de NUnit para verificar que el setter del indexador en mi simulacro someClass se estaba llamando con el valor correcto.

Parece que con Moq, la forma admitida de hacerlo es utilizar la función VerifySet. Un ejemplo artificial:

prueba
someClass.Object.SomeIndexedProperty[3] = 25; 
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25); 

La unidad pasa desde SomeIndexedProperty[3] se establece en 25, pero fallaría lo contrario.

+0

Tengo el mismo problema, solo mi propiedad indexada es de solo lectura, es decir, solo tiene un acceso directo 'get'. ¿Alguna idea sobre cómo puedo burlar esto? – MoonKnight

3

En su prueba, su único conjunto de expectativas para el comprador del indexador - y esto siempre devolverá el valor correspondiente de su matriz. El indexador no se comporta como una cosa real. Puede intentar algunas cosas para arreglarlo:

  1. Puede verificar si puede conectar este indexador. Personalmente, estoy usando RhinoMocks, así que no tengo idea de si esto se lleva a cabo

    someClass.SetupProperty(f => f.SomeIndexedProperty); 
    
  2. Usted puede tratar de burlarse de la incubadora, así y que sea para cambiar la matriz subyacente. Mi primera conjetura sería intentar algo en este sentido (sin garantía de que funcione):

    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>()) 
    .Callback((index, value) => someValues[index] = value); 
    
  3. O si la interfaz ISomeClass es lo suficientemente pequeño, usted podría crear una implementación de código auxiliar a sí mismo (que tendría el indexador implementado como un diccionario, variedad, etc.)

 

+0

# 1 no funcionó en mis experimentos. Intentaba hacer algo como # 2, pero no intenté una devolución de llamada. También gracias por señalar # 3 - a veces terminas tratando de clavar un tornillo en lugar de simplemente encontrar un destornillador. –

5

Usando Moq 3.1.416.3

instalación no funcionará para los indexadores (porque se necesita una expresión que significa instrucciones de asignación se descartan)

Así que hay que utilizar SetupSet como

_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>()) 
       .Callback<string,string>((key, value) => persistedValue = value); 

Una pequeña advertencia: esta expresión solo coincide si la clave es "MruNotes". No pude usar un matcher como It.IsAny para la clave.

Cuestiones relacionadas