Pregunta

Estoy tratando de escribir especificaciones para un controlador sin usar accesorios (en lugar de emplear modelos simulados). Este controlador requiere que un usuario inicie sesión, para lo cual estoy empleando AuthLogic , siguiendo el 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 sobre el efecto de:

Mock 'User_1005' received unexpected message :changed? with (no args)

No estoy seguro de cómo resolver esto; se burla con : cambiado? = > falso apropiado?

¿Fue útil?

Solución

Iain publicó una solución para usar objetos simulados con AuthLogic . Para reformular, los siguientes ayudantes van a 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 a mis especificaciones, y creo que hace exactamente lo que esperaba. Tengo especificaciones de controlador en funcionamiento que exploran modelos simulados para el usuario conectado, por lo que ahora no todos 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

P.S. Odio responder mi propia pregunta, pero esta es la respuesta que estaba buscando; Simplemente no lo encontré lo suficientemente temprano.

Otros consejos

Authlogic espera que el registro actúe como una instancia de registro activa. Puede usar una instancia real o un simulacro, pero si usa un simulacro / código auxiliar, debe asegurarse de que responda a todos los métodos requeridos por Authlogic.

Sugeriría usar un objeto de registro activo real en lugar de un simulacro. Si no desea usar un accesorio, puede usar una Fábrica.

La última opción sería pasar un simulacro que responda a cualquier método (puede lograrlo fácilmente mediante method_missing). El problema con esa solución es que no sabe de antemano qué valor debe devolver una llamada a un método específico.

Sí, puede pasar falso pero esto no es realmente una solución. Sería necesario probar / agregar manualmente un valor predeterminado hasta que encuentre que el objeto simulado responde a todas las solicitudes de Authlogic. Pero esto requeriría que siga constantemente authlogic para cualquier cambio interno para reparar las llamadas no respondidas a su código auxiliar.

En Rails 3 esta burla de UserSession ya no funciona, ya que la UserSession de AuthLogic no es una instancia de ActiveRecord :: Base. Solución que funciona para mí:

class UserSession < Authlogic::Session::Base
  extend ActiveModel::Naming
end

Encontré que burlarse de los objetos de autlogía eran difíciles y finalmente dejé de burlarme. En cambio, ahora uso un enfoque de generadores usando object daddy . Mis pruebas funcionales son mucho más felices ahora. Por cierto, debería ser + object_daddy absolutamente rocas. Los contextos transaccionales de Shoulda aseguran que mi base de datos de prueba permanezca limpia y no tengo que burlarme de objetos simples de registro activo en primer lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top