ruby-on-rails - current_user - gema devise
¿Cómo puedo usar modelos simulados en las especificaciones del controlador AuthLogic? (4)
Intento escribir especificaciones para un controlador sin usar accesorios (en cambio, empleando modelos simulados). Este controlador requiere que un usuario inicie sesión, para lo cual estoy empleando AuthLogic , siguiendo las recomendaciones del autor .
describe UsersController do
def mock_user(stubs={})
@mock_user ||= mock_model(User, stubs)
end
context ''when logged in'' do
before { activate_authlogic }
it "exposes the logged-in user as @user in response to GET (show)" do
UserSession.create(mock_user)
...
end
...
end
...
end
Todos estos ejemplos fallan en la línea UserSession.create(...)
, informando al efecto de:
Mock ''User_1005'' received unexpected message :changed? with (no args)
No estoy seguro de cómo resolver esto; se burla con :changed? => false
:changed? => false
apropiado?
Authlogic espera que el registro actúe como una instancia de registro activo. Puede utilizar una instancia real o una simulación, pero si utiliza una simulación / resguardo, debe asegurarse de que responda a todos los métodos requeridos por Authlogic.
Sugeriría utilizar un objeto de registro activo real en lugar de un simulacro. Si no quiere usar un accesorio, puede usar una fábrica.
La última opción sería aprobar un simulacro que responda a cualquier método (puede lograrlo fácilmente a través de method_missing). El problema con esa solución es que usted no sabe de antemano qué valor debe devolver una llamada a método específico.
Sí, puede pasar falso, pero esto no es realmente una solución. Se requeriría intentar / agregar manualmente un valor predeterminado hasta que encuentre el objeto simulado que responde a todas las solicitudes de Authlogic. Pero esto requeriría que usted siga constantemente authlogic para cualquier cambio interno para corregir llamadas no respondidas a su stub.
Descubrí que burlarse de los objetos authlogic era difícil y finalmente me rendí ante las burlas. En cambio, ahora uso un enfoque de generadores usando Object Daddy . Mis pruebas funcionales son mucho más felices ahora. Por cierto, debería + object_daddy absolutamente rock. Los contextos transaccionales de Shoulda aseguran que mi base de datos de prueba permanezca limpia y no tengo que burlarme de los objetos de registro activo simples en primer lugar.
Iain publicó una solución para usar objetos simulados con AuthLogic . Para reformular, los siguientes ayudantes entran en spec_helpers.rb
:
def current_user(stubs = {})
@current_user ||= mock_model(User, stubs)
end
def user_session(stubs = {}, user_stubs = {})
@current_user_session ||= mock_model(UserSession, {:user => current_user(user_stubs)}.merge(stubs))
end
def login(session_stubs = {}, user_stubs = {})
UserSession.stub!(:find).and_return(user_session(session_stubs, user_stubs))
end
def logout
@user_session = nil
end
He incorporado esto en mis especificaciones, y me parece que hace exactamente lo que esperaba. Tengo especificaciones de controlador en funcionamiento que exploran modelos simulados para el usuario que ha iniciado sesión, por lo que ahora no se rompen cuando agrego un campo al Usuario. El ejemplo de Iain de implementar esto en una especificación es como:
describe SecretsController do
before { login }
it "should be very very secret!"
end
PD Odio responder mi propia pregunta, pero esta es la respuesta que estaba buscando; Simplemente no lo encontré lo suficientemente temprano.
En Rails 3, esta burla de UserSession ya no funciona, ya que la UserSession de AuthLogic no es una instancia de ActiveRecord :: Base. Reparar eso funciona para mí:
class UserSession < Authlogic::Session::Base
extend ActiveModel::Naming
end