2010-01-29 11 views
11

Me he encontrado con este problema con las pruebas. Supongamos que tengo dos modelos, Usuario y Publicación, donde el usuario tiene_muchos: publicaciones.Comportamiento de la relación Mocking ActiveRecord en las pruebas RSpec

estoy tratando a las especificaciones a cabo un bloque de código que incluye algo como esto:

user = User.find(123) 
post = user.posts.find(456) 

sé cómo se burlan de los User.find y user.posts partes. El simulacro user.posts devuelve una matriz de objetos Post. Y cuando llega a la parte .find(456), todo se descompone con la excepción no block given.

Así que mi pregunta aquí es: ¿qué devuelvo como resultado de la simulación user.posts, por lo que el método .find(456) funciona en él? User.first.posts.class dice que es Array, pero obviamente hay algo más que hace que las llamadas de búsqueda de estilo AR funcionen. No me alegra la perspectiva de burlarme del método de búsqueda del objeto devuelto.

PS Antes de sugerir la respuesta obvia y buena de dejar de burlarse y usar accesorios/sembrar la base de datos de prueba con los datos necesarios, aquí está el esquema catch: legacy. Tanto el usuario como el correo trabajan en la parte superior de las vistas de la base de datos, no en las tablas, y cambiarlo para que sean tablas en la base de datos de prueba me parece incorrecto.

Respuesta

16

El problema es que user.posts no es en realidad un simple Array; es un objeto proxy de asociación. La forma de código auxiliar es probable que sea algo como esto (aunque la sintaxis exacta depende de qué burlarse marco que está utilizando):

def setup 
    @user = mock(User) 
    User.stub(:find).with(123).return(@user) 
    user_posts = mock(Object) 
    @user.stub(:posts).return(user_posts) 
    @post = mock(Post) 
    user_posts.stub(:find).with(456).return(@post) 
end 

Luego, en su prueba, User.find(123) volverá @user y @user.posts.find(456) volverá @post. Si necesita @user.posts para actuar como más de Array en sus pruebas, puede crear un mock(Array) y unir el método [](index).

+1

Esa es la forma 'feo' que no quería hacer, pero su mención de 'asociación objeto proxy' me proporcionó las palabras clave que me faltaban y su búsqueda me llevaron a lo que estaba buscando, ¡gracias! –

+7

@Toms, si su solución es única entre estas respuestas, quizás podría agregarla como una respuesta más. Me gustaría ver cómo lo resolvió. –

+0

La manera fea, se burla de burlas. Estaba feliz de entender esto, no era la primera vez que me encontraba con esta situación y me molestaba. –

7
+1

para rspec 3.2 [receive_message_chain] (https://relishapp.com/rspec/rspec-mocks/v/3-2/docs/working-with-legacy-code/message-chains) – ryan2johnson9

Cuestiones relacionadas