2011-03-09 17 views
12

Uso Rails 3.0.4 y RSpec 2.5. En mis controladores que utilizan named ámbitos en gran medida, por ejemploRails 3, RSpec 2.5: Usar should_receive o stub_chain con ámbitos con nombre

 
    @collection = GuestbookEntry.nonreplies.bydate.inclusive.paginate(
     :page => params[:page], :conditions => { ... }) 

En mis pruebas, quiero ser capaz de burlar el resultado de dicha consulta, no el redacción. Creo que no tiene sentido hacer algo como

 
    GuestbookEntry.stub_chain(:nonreplies, :bydate, ...).and_return(...) 

ya que esta prueba fallará el momento en que decido cambiar el orden de los ámbitos mencionados.

con los carriles de 2.3 y 1.x RSpec, esto funcionó bien: se podría escribir

 
    GuestbookEntry.should_receive(:find).with(:all, :conditions => { ... }) 

y la llamada anterior sería capturados y manipulados correctamente. Sin embargo, con Rails 3, por alguna razón, esto ya no funciona.

¿Por qué? ¿Cómo configuro expectativas o talones en el resultado de ámbitos anidados? Dado que todo en ActiveModel de Rails 3 es un ámbito con nombre (gracias a ARel), esto debe ser posible de alguna manera, o las pruebas serían de hecho muy frágiles.

Gracias!

Actualización: Véase también issue report on GitHub.

Respuesta

1

¡Este problema me ha molestado por un tiempo también!

Creo que el motivo por el que el comportamiento es diferente de Rails 2 es porque la consulta ya no se realiza durante la asignación de variables en el controlador. En cambio, se carga de manera diferida según sea necesario.

Estoy de acuerdo con Mark Wilden en que es mejor ajustar todos estos ámbitos en un ámbito más amplio y especificarlo en su modelo. Este ámbito claramente tiene una función específica, así como uno especificaría el comportamiento de un método que llama a varios otros métodos, se especificaría el comportamiento de un ámbito que se une a otros muchos ámbitos.

0

me envolvería una consulta tan complicada en su propio ámbito, resguardo y eso.

+0

Entonces, ¿cómo escribo especificaciones que verifican que el único alcance hace lo que se supone que debe hacer? Mi idea era escribir varios _simple_ scopes que son _obvious_ para que casi nada dentro de ellos pueda "salir mal", y luego combinarlos, porque es tan difícil de alcanzar ámbitos (sin recurrir a poblar y consultar una base de datos real con datos reales)) – Jens

+0

Creo que debe especificar cada "alcance completo", de lo contrario no sabrá que los combinó correctamente. Incluso si especifica que se hizo la combinación correcta, necesita una especificación global para mostrar que esa combinación en sí misma fue la forma correcta de resolver el problema. Pero si pone el alcance complicado en su propio ámbito, al menos no tiene que preocuparse por el orden de la "redacción", ya que solo se realiza en un solo lugar. No creo que pueda evitar llenar una base de datos. Personalmente, me resulta más fácil (y "más seguro") utilizar fábricas para configurar datos reales que para burlar los métodos del modelo. –

Cuestiones relacionadas