2009-07-29 10 views
24

mi equipo ha tomado la decisión recientemente de usar Moq como nuestro marco burlón por su gran flexibilidad y sintaxis altamente legible. Como somos nuevos en esto, me estoy tropezando con lo que parecen ser preguntas simples: las búsquedas (aquí, Google, etc.) encuentran muchas discusiones sobre otros matices de Moq, pero no necesariamente lo que busco, y las pocas preguntas aparentemente relacionadas se han convertido en pistas falsas.Métodos de vacío en "cortocircuito" con Moq?

Estamos probando una clase que tiene una dependencia externa (Amazon SimpleDb para ser precisos) pero no queremos que nuestras pruebas tengan una conexión en vivo. Un método particular:

  • Se aplica una lógica de "negocios"
  • Si es apropiado, invoca una llamada a SDB través de un proveedor que hemos construido, vamos a llamarlo SaveItem()

Quiero unidad Pruebe esto para que configuremos el contexto requerido y aseguremos que se invocó SaveItem(), pero de una manera que SaveItem() realmente no se invoca (porque A) el proveedor de SDB es un simulacro que no está completamente hidratado y es probable que bombardee y B) No quiero tener que pagar por esa transacción cientos y miles de veces).

Cuando se trataba de métodos que devolvían un valor, esto era trivial.

mockDb.Setup(d => d.GiveMeSomething()).Returns("Foo"); 

En el caso de que describo más arriba, sin embargo, mi método "SaveItem()" es nula y por lo tanto la opción de utilizar el método de Moq Returns() no está disponible. Y aunque puedo configurar una devolución de llamada para verificar que se invoque SaveItem(), parece que no puedo lograr que no haga nada.

Naive/esperanzador, pensé que el siguiente iba a funcionar, pero parece que todavía invocar el método:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())); 

Así que la pregunta del millón: ¿Cuál es la Moq del siguiente código ficticio?

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).STOP_RIGHT_HERE(); 
+0

Editado para aclarar la situación, la prueba es para una clase "business" flotando alrededor, no para la implementación real SimpleDB. La implementación de SimpleDB se prueba en otro lugar, aquí, es de lo que me estoy burlando. – bakasan

Respuesta

29

Si el método SaveItem() es virtual o abstracta, y no se está configurando Callbase = true, entonces el método se debe volver a implementar para no hacer nada por el simulacro.

Usted debe ser capaz de hacer:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).Verifiable(); 

... test here ... 

mockDb.Verify(); 
+0

¡Perfecto! Absolutamente no tenía idea de que era la intención del material Verificable()/Verificar(), y sin documentación más formal, ni siquiera habría sabido leer los hilos y las publicaciones en esa área. Acabo de darle un giro y ahora tengo casos de prueba tanto positivos como negativos en este escenario. ¡Muchas gracias! – bakasan

+2

+1; Además, también puede verificar todas sus llamadas independientemente del indicador Verificable() llamando a mockDb.VerifyAll() –

+0

Posible que esta respuesta se expanda para el otro escenario, es decir, ¿el método no es virtual ni abstracto? – leon