2011-02-03 9 views
6

Soy nuevo en Rspec e intento configurar una prueba para un perfil de usuario. Perfil belongs_to Usuario.burla de Rspec: ActiveRecord :: AssociationTypeMismatch

Ahora, tengo una integración API con un sitio de terceros que funciona a través del Modelo de usuario, pero parte de la información para ese enlace API está en Perfil, así que tengo un filtro "after_update" en Perfil que le dice al usuario principal para guardar, lo que desencadena una actualización de la API.

Estoy tratando de escribir una prueba para esto, y estoy obteniendo un ActiveRecord :: AssociationTypeMismatch. La razón es que estoy usando un usuario simulado, pero estoy tratando de probar que cuando se actualice el Perfil envíe: guardar en Usuario. Además, el modelo de usuario tiene un proceso de confirmación por correo electrónico y las llamadas de API mencionadas en su proceso de creación, por lo que realmente no es ideal crear un usuario solo para probarlo.

Aquí está mi prueba:

it "should save the parent user object after it is saved" do 
    user = double('user', :save => true) 
    profile = Profile.create(:first_name => 'John', :last_name => 'Doe') 
    profile.user = user 

    user.should_receive(:save) 
end 

Por lo tanto, claramente el error ActiveRecord está siendo causado por tratar de asociar un usuario maqueta con un perfil que espera que un usuario real que se asocia.

Mi pregunta es, ¿cómo evitar este tipo de problema al escribir pruebas de rieles? Todo lo que quiero que haga esta prueba es asegurarme de que Profile calls: save on it's User. ¿Existe alguna forma más inteligente de hacerlo o una solución para el error de ActiveRecord?

Gracias!

+0

Personalmente, utilizaría algo como factory_girl para crear un objeto User ya confirmado y luego establecer la expectativa 'save' sobre eso. ¿No puede falsificar a un usuario confirmado sin pasar por el proceso del correo electrónico? Eso activa algunas alarmas con respecto al diseño del código. –

+0

Bueno, tu sugerencia terminó siendo la forma en que tuve que ir. Pude aislar la API que no quería que se llamara diciéndole al controlador que no active esa llamada en el entorno de prueba, por lo que me permitió trabajar con los objetos de fábrica como se esperaba. Sin embargo, tuve que volver a activar las acciones de la API para probar las integraciones, así que al final abandoné este enfoque y estoy permitiendo que el entorno de la zona de pruebas para la API se llene de datos no deseados que tengo que borrar periódicamente. No es lo que hubiera preferido, pero me deja probar. – Andrew

Respuesta

3

me pareció la única forma que era capaz de solucionar este problema era utilizar un usuario de fábrica en lugar de una maqueta. Eso es frustrante, pero al probar las devoluciones de llamada entre dos modelos de ActiveRecord, debe usar los modelos reales o, de lo contrario, las llamadas de guardado fallarán, el ciclo de vida no ocurrirá y las devoluciones de llamada no se podrán probar.

+0

¿No deberían probarse las devoluciones de llamada en la especificación del modelo pertinente? – Starkers

11

Usted debe ser capaz de utilizar una mock_model para esto:

it "should save the parent user object after it is saved" do 
    user = mock_model(User) 
    user.should_receive(:save).and_return(true) 
    profile = Profile.create(:first_name => 'John', :last_name => 'Doe') 
    profile.user = user 
end 
+0

Intenté esto y no funcionó. – Andrew

+2

¿Qué específicamente? – zetetic

+0

Funciona. ¡Gracias! –

Cuestiones relacionadas