Estado del arte en Mock Frameworks

76 views
Skip to first unread message

Ernesto Cárdenas

unread,
Jul 12, 2012, 2:33:17 PM7/12/12
to AltNet-Hispano
Hola todos

Recientemente me he visto puesto en la necesidad de ir lidiando y
revisar DI (aaay) y frameworks Mock, lo cual me llevo a volver a ver
un viejo conocido de antiguos tutoriales: Rhino.

El caso es que en la búsqueda de bibliografía, encontré los libros de
Osherove, notando de manera curiosa que en su nueva edición ya no
incluirá ejemplos en Rhino, lo cual me llevo a darle un vistazo
(gracias a un mensaje favorable en StackOverflow de Mark Seeman) a
Moq, el cual me dio una buena impresión en el sentido de tener una
declaración menos "verbosa" y que trata de abstraerte de la duda
filosófica de si es un stub o un mock...

Todo bien hasta ahi, pero a poco de ir buscando me entero de que el
propio Osherove dijo algo como "it's a no brainer - FakeItEasy is the
new Moq", lo cual me derivo a estos articulos en el blog de Roy:
http://osherove.com/blog/2012/6/27/the-future-of-isolation-frameworks-and-how-moq-isnt-it-for-n.html
http://osherove.com/blog/2012/6/26/fakeiteasy-or-nsubstitute-which-should-i-use-for-samples-in.html

En concreto, el nuevo libro (a diferencia de lo indicando en la web
del editor, Manning) no incluirá ejemplos de Moq, planteando al
publico sobre usar NSubstitute o FakeItEasy, fundamentalmente porque
(según él) estan yendo mas allá en lo de plantear una API simple, mas
usable y que te evite confusiones (nuevamente ¿stubs o mocks?)

Como nuevo caído a este mundo debo decir que efectivamente Rhino esta
muy por detras en termino de facilidad, los ejemplos que he podido ver
son menos intuitivos (lo de "Record" no lo entiendo la verdad) y
hacerme a Moq no me ha costado mucho, pero si hay que dar un paso mas
alla ¿cual seria la eleccion de ustedes? ¿NSubstitute o FakeItEasy?

Saludos
Ernesto

Angel Java Lopez

unread,
Jul 12, 2012, 2:46:54 PM7/12/12
to altnet-...@googlegroups.com
Hola gente!

Moq esta muy bien. Lo vi usado en varios proyectos y no tuvo mayor problema. Tendria que ver algun proyecto con
http://nsubstitute.github.com/ 

Jajaja.... no quiero una "flame war", pero tengo que decir, para mis biografos y abogados:

"El mejor mock es el mock muerto" ;-) Es decir, usar mocks lo menos posible. Pero bue... puede ser una discusion larga. Debe haber defensores y opositores de esta postura, y al final, seguramente dependera del contexto, como cuando se usa o no un patron.

Nos leemos!

Angel "Java" Lopez


2012/7/12 Ernesto Cárdenas <ernesto....@gmail.com>
Ernesto

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/altnet-hispano?hl=es.


Ernesto Cárdenas

unread,
Jul 12, 2012, 2:51:01 PM7/12/12
to AltNet-Hispano
Hola Angel

Buena respuesta, pues bien... por lo que veo los de NUnit colocan un
mensaje a su antiguo NUnit.Mocks: [Obsolete("NUnit now uses
NSubstitute")]

On Jul 12, 1:46 pm, Angel Java Lopez <ajlopez2...@gmail.com> wrote:
> Hola gente!
>
> Moq esta muy bien. Lo vi usado en varios proyectos y no tuvo mayor
> problema. Tendria que ver algun proyecto conhttp://nsubstitute.github.com/

José F. Romaniello

unread,
Jul 12, 2012, 4:12:20 PM7/12/12
to altnet-...@googlegroups.com

El 12 de julio de 2012 15:46, Angel Java Lopez <ajlop...@gmail.com> escribió:
"El mejor mock es el mock muerto"

si, pero recuerdo que moq es un buen framework de stubs ;)

Daniel Cazzulino

unread,
Jul 12, 2012, 4:13:19 PM7/12/12
to altnet-...@googlegroups.com

Efectivamente alternativas como NSubstitute proveen en algunos casos APIs más bonitas que Moq. Es algo que v5 va a resolver.

Hay varias cositas q en NSubstitute son mas feitas, por ej. eso de callbacks en los argumentos, cuando tenes metodos void es lo mismo q Moq basicamente (pero When en vez de Setup y Do en vez de Callback), con la desventaja de q por ejemplo hacer el Throw de algo es medio feito (en Moq es solo Setup(...).Throws<Exception>(). 

No coincido tanto con lo de strict mocks, aunq personalmente no los uso practicamente nunca. Por ahi tiene razon el tema de q cualquier API, con el tiempo, puede quedar un poco desactualizada cuando nuevos patrones y mejores practicas van surgiendo.

Tambien algo q Moq v5 va a descollar, porq va a permitir q cualquiera pueda escribir "flavors" de APIs arriba de Moq Core/SDK ;)

/kzu from mobile


/kzu

--
Daniel Cazzulino


2012/7/12 Ernesto Cárdenas <ernesto....@gmail.com>

Ale Miralles

unread,
Jul 12, 2012, 4:37:02 PM7/12/12
to altnet-...@googlegroups.com
Ninguna, me quedo con Moq ;)
La verdad es que hasta ahora no encontré limitaciones en Moq que me hagan
pensar en un cambio, no sé cómo estarán encarando el tema de WinRT, pero
para todo lo que es .NET <= 4.0 funciona muy bien.
Por varios años utilice Rhino, pero la verdad es que la sintaxis va para
atrás (incluso la fluent API de las últimas versiones) eso me llevó a probar
Moq y fue un camino de ida.
Con respecto al tema de las APIs.... más simple que Moq?, de verdad?!... ;)

Saludos, Ale Miralles
http://amiralles.com.ar


-----Mensaje original-----
De: altnet-...@googlegroups.com [mailto:altnet-...@googlegroups.com]
En nombre de Ernesto Cárdenas
Enviado el: jueves, 12 de julio de 2012 15:33
Para: AltNet-Hispano
Asunto: [altnet-hispano] Estado del arte en Mock Frameworks

Ariel Piñeiro

unread,
Jul 12, 2012, 4:42:50 PM7/12/12
to altnet-...@googlegroups.com
+1 Moq, es difícil resistirse a la tentación con nuget, visual studio y tu primer unit test de la aplicación.




Saludos,
Ariel Piñeiro
http://ar.linkedin.com/in/arielpineiro



2012/7/12 Ale Miralles <amiral...@gmail.com>

Ernesto Cárdenas

unread,
Jul 12, 2012, 4:59:31 PM7/12/12
to AltNet-Hispano
Reitero, como novato total ver Moq es percibir simplicidad al lado de
la complejidad de sintaxis de Rhino, ahí la "ganancia" para mi es
evidente, lo que no tengo tan claro (como si parece serlo para
Osherove) es que esta sea tan evidente con estos otros dos frameworks
al lado de Moq. Sera cuestión de ver como terminan decantándose las
cosas en los proximos meses ;) igual hay algo de .Net 4 o 4.5 que
ayude a simplificar las cosas.

Jorge Fioranelli

unread,
Jul 12, 2012, 5:29:42 PM7/12/12
to altnet-...@googlegroups.com
Estoy muy interesado en saber que tecnica utilizan aquellos que no utilizan ningun framework.

Escriben los stubs a mano para cada dependencia?
Tambien me gustaria preguntar que ventaja encuentran respecto a usar un framework.

Yo he usado las dos tecnicas en proyectos grandes y tengo mis propias respuestas :), pero me gustaria escuchar las del resto.

Saludos

JorgeF

2012/7/13 Ernesto Cárdenas <ernesto....@gmail.com>

José F. Romaniello

unread,
Jul 12, 2012, 6:10:17 PM7/12/12
to altnet-...@googlegroups.com
Si, stubs a mano o usar las dependencias reales en algunos casos. Hay dos aspectos fundamentales en opinión:

1- top-down vs botton-up. Cuando hago TDD prefiero hacerlo de una forma en el que la arquitectura emerja (top down) y ya no entiendo cuando alguien intenta explicar TDD creando un mock de irepository para escribir  un test de controller, para mi repository nace de un refactoring en la mayoría de los casos. Estoy de acuerdo que en algunos casos puede ser mejor botton up, pero en mi experiencia top-down es mejor. Y también acepto que hay mucha gente que prefiere botton up siempre.

2- CQS. Command o query. Sii el SUT es un query no hay razón alguna para usar un mock, solo puede hacer falta stubs. Si es command puede ser necesario un mock.. por lo general hay muchos mas Q que C.

Jorge Fioranelli

unread,
Jul 12, 2012, 7:13:42 PM7/12/12
to altnet-...@googlegroups.com
Muchas gracias Jose por las respuestas. Si no te molesta que pregunto un poco mas, quiero estar seguro de haber entendido :)

1- entiendo la diferencia entre las dos tecnicas, pero no entendi como es mejor un stub/dependencia real vs un mock. Al momento del refactoring, cuando detectas la necesidad de una dependencia, en que te ayuda usar un stub/dependencia real vs un mock? que perdes usando un mock y que ganas no usandolo? 

2- esto significa que los queries los ejecutas siempre contra la base de datos en los unittests y que para los commands puede que uses mocks y no la db?

Muchas gracias de nuevo

Saludos

JorgeF 



2012/7/13 José F. Romaniello <jfroma...@gmail.com>

José F. Romaniello

unread,
Jul 12, 2012, 7:32:28 PM7/12/12
to altnet-...@googlegroups.com
In line


El jueves, 12 de julio de 2012, Jorge Fioranelli escribió:
Muchas gracias Jose por las respuestas. Si no te molesta que pregunto un poco mas, quiero estar seguro de haber entendido :)

1- entiendo la diferencia entre las dos tecnicas, pero no entendi como es mejor un stub/dependencia real vs un mock. Al momento del refactoring, cuando detectas la necesidad de una dependencia, en que te ayuda usar un stub/dependencia real vs un mock? que perdes usando un mock y que ganas no usandolo? 

Hablemos de usar la dep. real; si hago top down, al primer test que escribo no puedo escribir el mock por que todavía no se si existe o va existir esa dependencia. Un repositorio, o una clase que haga parte de esa funcionalidad que estoy especificando puede surgir despues de las primeras especificaciones como refactoring, y cuando surja no voy a volver a reescribir las especificaciones que ya hice antes para usar mock, a lo sumo cambiar la forma como se construye el objeto.

 

2- esto significa que los queries los ejecutas siempre contra la base de datos en los unittests y que para los commands puede que uses mocks y no la db?

Cuando hablo de query en el sentido de CQS no solo hablo de db, cualquier metodo que sirva para devolverme un resultado sin side effect. En este caso me permito usar dep. reales, un stub creado a mano o un stub creado por un framework como Moq prro JAMAS necesitaría un mock. Es decir configurar un objeto con un metodo que devuelva cierto resultado,... Pero nunca necesitaría escribiría en este caso un assert.called o similar.

Jorge Fioranelli

unread,
Jul 12, 2012, 8:38:48 PM7/12/12
to altnet-...@googlegroups.com
Gracias de nuevo. Me quedo claro el punto 2. 

Respecto al punto 1: si escribo el test sin pensar en la dependencia (y por lo tanto si el mock) y luego haciendo refactoring encuentro que necesito una dependencia, no puedo ahi agregar el mock en el test inyectarlo? Entiendo que no arrancas pensando en las dependencias, sino que surgen ante la necesidad. Pero sigo sin entender que beneficio tenes al no usar un mock? Estoy entendiendo cualquier cosa?

Saludos

Jorge

Jorge Fioranelli

unread,
Jul 12, 2012, 8:40:33 PM7/12/12
to altnet-...@googlegroups.com
Correcciones:

(y por lo tanto si el mock) =>  (y por lo tanto siN el mock) 
no puedo ahi agregar el mock en el test inyectarl =>  no puedo ahi agregar el mock en el test E inyectarlo 


2012/7/13 Jorge Fioranelli <jorge.fi...@gmail.com>

Ariel Piñeiro

unread,
Jul 13, 2012, 9:09:57 AM7/13/12
to altnet-...@googlegroups.com
Hablando de mock... la VAN de Angel de TDD está subida?
2012/7/12 Jorge Fioranelli <jorge.fi...@gmail.com>

Esteban Grinberg

unread,
Jul 13, 2012, 9:40:10 AM7/13/12
to altnet-...@googlegroups.com
A mi nunca me gusto mucho usar mocking. Me parece una fantastica idea, pero con un costo de implementacion bastante alto y ademas hace bastante mas complejo el test unitario (cuando por lo menos para mi, deben ser lo mas simple posible. Despues cuando algo falla, no sabe si es por culpa del metodo a testear, o del propio metodo de test unitario). Por suerte paso esa moda de hacer un mock hasta de un "Hola Mundo". Como siempre en el mundo del desarrollo, cuando aparece una nueva tecnologia o framework, muchos programadores la utilizan hasta en la sopa, pero despues las ideas maduran y se hace un uso mas inteligente y moderado del mismo.
Creo que es el caso de los mocking.
Para el caso, segun mi experiencia personal al menos, yo prefiero seguir haciendo un test unitario que escriba en la db. Realmente son muy pocos los casos, donde esto realmente pueda representar un problema real y me afecte la calidad o validez del test unitario.

Saludos,
Esteban

2012/7/13 Ariel Piñeiro <arie...@gmail.com>

José F. Romaniello

unread,
Jul 13, 2012, 9:58:08 AM7/13/12
to altnet-...@googlegroups.com


El 12 de julio de 2012 21:38, Jorge Fioranelli <jorge.fi...@gmail.com> escribió:
luego haciendo refactoring encuentro que necesito una dependencia, no puedo ahi agregar el mock en el test inyectarlo? Entiendo que no arrancas pensando en las dependencias, sino que surgen ante la necesidad. Pero sigo sin entender que beneficio tenes al no usar un mock?

qué beneficio tenes al volverte sobre un test y modificarlo?

Intento dar un ejemplo, (siguiendo con controller-repository-bd que es lo que todos manejamos).


Necesitabas un método en un controller que devuelva una lista clientes ordenados por nombre en páginas, y escribimos un test así en pseudocódigo

[test]
public void .... (){
   insertCustomer("Jose", "Romaniello", ...);
   insertCustomer("Jorge", "Fioranelli", ...);
   insertCustomer("Dario", "Perez", ...);
   
  var result = controller.get(....)
  result...should()...xyz
}


Y supongamos que ese insertCustomer usa una bd de pruebas. Ahora te diste cuenta que el controller esta teniendo mucha lógica de acceso a datos mezclada y que esta teniendo muchos concerns diferentes y quisieras extraer la lógica de la consulta a una clase aparte. Lo haces y la extraes.

Mi opción es:

reemplazar en algún lugar new CustomerController(connectionString) por new Controller(new CustomersSortedByNameQuery(connectionstring))

Tus opciones podrían ser:

1- ir y reemplazar los inserts a la bd de prueba, por algún collection.add etc. y inyectarle al controller un mock(stub) que toma los valores de la lista en memoria
2- modificar la parte de arrange del test para que no inserte nada y crear un stub que devuelva esos tres resultados

mi pregunta en ese caso es que ganas en ese caso usando un mock? Por que desde mi punto de vista tiene una gran desventaja que es que te fuerza a modificar bastante una especificación que ya estaba escrita a causa de un refactoring.

No digo que esto aplique para todos los casos, mi punto con esto es que me parece que los "fakes"  (mock/stub o lo que sea) están sobrevaluados.

Matias Woloski

unread,
Jul 13, 2012, 10:08:00 AM7/13/12
to altnet-...@googlegroups.com
+1, me hace acordar a la discusión que surgió hace un par de años de state-based vs interaction-based testing… cuanto menos incumbencia tenga el test con lo que esta abajo y mas cercano a lo que se terminara ejecutando realmente, mas valioso va a ser (por lo menos eso es lo que me muestra la experiencia). Hoy en día también es mucho mas fácil setupear un environment para tus tests (sql ce, ef code first, migrations, nosql, etc.).
--

cibrax

unread,
Jul 13, 2012, 10:25:49 AM7/13/12
to altnet-...@googlegroups.com
En visual studio 2012 viene un feature que se llama Fake y que todavia no mire con mucho detalle, pero basicamente te genera un stub de cualquier clase que quieras. Hasta le podes pasar un assembly, y te genere stubs para todas las clases en en el assembly y te lo agrega al proyecto de test.
 
Por el lado de Mock frameworks, me quedo con Moq toda la vida.
 
Saludos
Pablo.

cibrax

unread,
Jul 13, 2012, 10:28:54 AM7/13/12
to altnet-...@googlegroups.com
Otra cosa. Hay algunas cosas que son realmente complejas de testear sin un mock o stub. Si bien, la interaccion con una base de datos se simplifico, a veces tenes escenarios en el cual tenes que pegarle a servicios externos o web services, y que no vale la pena invertir un monton de tiempo para hostearlos como parte del test.
 
El jueves, 12 de julio de 2012 15:33:17 UTC-3, Ernesto Cárdenas escribió:

Ale Miralles

unread,
Jul 13, 2012, 1:05:16 PM7/13/12
to cibrax, altnet-...@googlegroups.com
Totalmente!

Sent from my Windows Phone

From: cibrax
Sent: 7/13/2012 11:28
To: altnet-...@googlegroups.com
Subject: [altnet-hispano] Re: Estado del arte en Mock Frameworks

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para ver este debate en la Web, visita https://groups.google.com/d/msg/altnet-hispano/-/zZ_ZdHrM8DwJ.

Jorge Fioranelli

unread,
Jul 13, 2012, 5:58:36 PM7/13/12
to altnet-...@googlegroups.com
Gracias Jose, ahí entendí! Mi confusión era que pensé que en ese punto también estabas hablando de armar un stub a mano en lugar de usar un framework. 

Concuerdo que usar la dependencia real muchas veces simplifica bastante el test (aunque tambien es verdad que otras veces hace mas difícil testear ciertos escenarios).

Yo tuve la suerte de usar las tres técnicas en proyectos medianos y grandes (en los chicos cualquiera funciona bien), y en mi humilde opinión todos tienen pros y contras.

Dependencias reales: test mas simples pero agregan complejidad para testear ciertos escenarios. En el caso de estar accediendo a una base de datos, en ciertos escenarios complejos se necesita bastante código para setear la base en el estado esperado (a menos que se posea una base con todos los escenarios ya insertados).

Stubs manuales: simplifican el setup en los tets ya que retornan siempre el escenario mas usado, pero en proyectos grandes agregan un buen numero de clases extras (en uno teníamos alrededor de 70). Necesitan tener lógica que setee flags/campos internos para validar el resultado (siempre que escribo este tipo de código siento que estoy reescribiendo lo que los frameworks me dan gratis).

Frameworks de Mocks/Stubs: agregan complejidad en los tests, ya que el setup en casos complejos no es menor (hasta a veces ensucian bastante el test). Requieren extra conocimiento de como usarlos. Muchas veces el mismo setup se repite varias veces porque es necesario en varios tests (pero no en todos, con lo cual no se puede poner en el init), en esos casos suelo crear métodos privados o extension methods para reusar el setup. 

No creo que haya un método perfecto (o por lo menos no lo encontré), pero por ahora me sigo quedando con los frameworks, aunque siempre estoy interesado en ver la soluciones que usa el resto, y dispuesto a cambiar un poco.

En cuanto a los frameworks use rhino, moq y nsubstitute. Como dice kzu, nsubstitute es el mas simple pero a veces se complica un poco al tratar de hacer cosas mas complejas. Creo que moq tiene un buen balance.

Saludos

JorgeF
--

Jorge Fioranelli

unread,
Jul 13, 2012, 7:35:45 PM7/13/12
to altnet-...@googlegroups.com
Me quede pensando en este comentario de kzu.

Recuerdo cuando salió Moq, todos lo amábamos porque era mas simple que Rhino y usaba lambdas :). Aunque Rhino agrego lambdas también, todos nos quejábamos de que tenía muchas formas de hacer lo mismo y por lo tanto la api era muy confusa. A lo que muchos contestaban que era debido a que tenía que mantener la compatibilidad para atrás (lo cual era totalmente cierto).

Como son las vueltas de la vida que ahora Moq se encuentra en una situación parecida... Va a ser un gran desafío para Moq.

Saludos

JorgeF
Reply all
Reply to author
Forward
0 new messages