tutorial rails factorybot example bot ruby-on-rails ruby unit-testing rspec factory-bot

ruby on rails - rails - Dónde usar `FactoryGirl.build_stubbed` y dónde usar` simulacro/`doble`



rspec factory bot (1)

Solo tengo curiosidad por saber dónde las personas tienden a usar FactoryGirl.build_stubbed y dónde usan el double al escribir las especificaciones de RSpec. Es decir, ¿existen prácticas recomendadas como "solo usar los métodos FactoryGirl en sus especificaciones de modelo correspondientes?"

¿Es un olor de código cuando te encuentras usando FactoryGirl.create(:foo) en spec / models / bar_spec.rb?

¿Es un olor de código menor si está utilizando FactoryGirl.build_stubbed(:foo) en spec / models / bar_spec.rb?

¿Es un olor de código si estás usando FactoryGirl.create(:foo) en foos_controller_spec.rb?

¿Es menos olor a código si estás usando FactoryGirl.build_stubbed(:foo) en foos_controller_spec.rb?

¿Es un olor de código si está utilizando FactoryGirl.build_stubbed(:foo) en spec / decorators / foo_decorator_spec.rb?

¡Perdón por tantas preguntas! Me encantaría saber cómo otras personas dibujan las líneas en el aislamiento de prueba unitaria y las mejores prácticas de diseño orientado a objetos.

¡Gracias!


Creo que existen prácticas recomendadas que nos guían a pensar cuándo usar simulacros (en este caso, "se duplica") en comparación con la integración contra dependencias reales (en este caso, "Fábricas"). Hay un muy buen libro sobre pruebas (advertencia: utiliza ejemplos de Java) que describe el propósito del desarrollo basado en pruebas, y creo que es muy útil en esta discusión sobre las pruebas en aplicaciones Rails. Describe la intención de la prueba de la siguiente manera:

... nuestra intención en el desarrollo guiado por pruebas es usar objetos simulados para resaltar las relaciones entre los objetos.

Freeman, Steve; Pryce, Nat (2009-10-12). Software creciente orientado a objetos, guiado por pruebas (ubicaciones Kindle 3878-3879). Pearson Education (Estados Unidos). Versión Kindle.

Si pensamos en este énfasis en usar el desarrollo guiado por pruebas no solo para evitar que introduzcamos regresiones, sino para ayudarnos a pensar cómo está estructurado nuestro código en términos de su interfaz y relaciones con otros objetos, naturalmente usaremos simulacros en muchos casos. . Describiré cómo esto se aplica a sus preguntas específicas a continuación.

Primero, en términos de si usamos objetos simulados o dependencias reales en modelos de prueba: si estamos probando la clase Foo y su dependencia de Bar, es posible que deseemos sustituir un simulacro por Bar. De esta manera veremos claramente el nivel de acoplamiento a Bar, ya que tendremos que burlarnos de los métodos a los que se recurrirá. Si descubrimos que nuestro simulacro de Bar es complejo, es una señal de que quizás deberíamos refactorizar a Foo y Bar para que estén menos acoplados entre sí.

En el sentido de que tanto Factory.create como Factory.build_stubbed tienen el mismo efecto de evitar que las dependencias de las clases relacionadas sean explícitas, creo que ambas son igual de malolientes, siendo Factory.create la opción más lenta.

En mis pruebas tiendo a no preocuparme demasiado por burlarse de las dependencias externas en los controladores. Sé que esto es más lento de ejecutar que completamente burlón, y no tiene la ventaja de hacer que el controlador se acople al modelo de manera explícita, pero es más rápido escribir la prueba, y en general no estoy tan preocupado por dejar en claro el Relación entre los controladores y los registros persistentes que manejan. Mientras sigas los patrones de "controladores flacos" no debería haber demasiada lógica de qué preocuparse aquí de todos modos. Si tuviéramos que especificar un nivel de "olor a prueba" aquí, diría que es un poco menos maloliente que las pruebas modelo que dependen de otras fábricas.

Tendría que preocuparme menos por los decoradores que dependen de las fábricas de las clases que decoran. Esto se debe a que, por definición, el decorador debe mantener la misma interfaz que la clase que decoran. La decoración se implementa con mayor frecuencia con algún tipo de herencia, ya sea mediante el uso de method_missing para delegar en el decoratee, o mediante la subclase explícita del decoratee. Debido a esto, usted está rompiendo otras reglas de buena programación orientada a objetos como la sustitución de Liskov si el decorador se desvía demasiado de la interfaz de lo que decora. Si su decoración no se implementa de manera deficiente al romper las reglas de una buena herencia, el acoplamiento a la clase que usted decora ya está presente, por lo que no está empeorando las cosas si la prueba de la decoración depende de una persistencia o rechazo Fábrica de lo que decora. Puedes volverte loco con las fábricas en las pruebas de decoración y no importa la OMI.

Creo que es importante tener en cuenta que incluso si prefieres simulacros en la mayoría de los casos, deberías tener algunas pruebas de integración que usen dependencias reales. Encontrará que estos cubren casos específicos de alto valor, donde las pruebas de unidades aisladas brindan más cobertura de la funcionalidad proporcionada por sus clases.

En cualquier caso, a veces rompo todas las reglas anteriores y son solo algunas pautas que utilizo al escribir exámenes. Estoy deseando escuchar cómo otros usan Fábricas (build_stubbed y realmente persisten) versus objetos simulados (dobles) en sus pruebas.