2010-09-07 3 views
0

У меня возникли проблемы с издевательством authlogic from shoulda.Mocking authlogic from toa with mocha

У меня есть следующий тестовый прибор:

class HomeControllerTest < ActionController::TestCase 
    context "on GET to index" do 
    setup do 
     activate_authlogic 
     UserSession.stubs(:current_user).returns(user_session) 
     get :index 
    end 

    should respond_with :success 
    end 

    def user_session 
    @user_session.stubs(:user).returns(Factory.build(:user)) 
    @user_session.stubs(:record) 
    @user_session 
    end 
end 

Проблема заключается в том, что метод require_user в ApplicationController все еще не получают CURRENT_USER.

def current_user 
    puts "#{defined?(@current_user)}" 
    return @current_user if defined?(@current_user) 
    @current_user = current_user_session && current_user_session.record 
end 

def require_user 
    unless current_user 
    store_location 
    flash[:notice] = "You must be logged in to access this page" 
    redirect_to login_url 
    return false 
    end 
end 

Может ли кто-нибудь увидеть, что не так?

ответ

0

Я думаю, что проблема может быть в последней строке в вашем методе current_user.

Возможно, вам захочется разбить его на несколько строк, чтобы сделать его более читаемым и легче диагностировать, какие части этого утверждения не так, как вы ожидали бы в своем тесте.

E.g.

@current_user = current_user_session 
@current_user.record if @current_user 
return @current_user 
+0

Последняя строка метода current_user прямо из AuthLogic. В Ruby строка, подобная 'result = foo && foo.bar', является удобным сокращением для« задавать значение результата переменной атрибуту bar объекта foo, но только если задана переменная foo ». 'foo && foo.bar' вернет' nil', если foo не был установлен. Если foo установлен, то возвращается значение foo.bar. – Chris

+0

Достаточно справедливо, но я все же думаю, что расширение его на большее количество строк облегчит выяснение того, что происходит в тесте. Я обновил свой ответ, чтобы удалить неверное предположение о возвращаемом значении. – Shadwell

+0

Также является ли возвращаемое значение метода current_user не значением 'current_user_session.record'? Который, если что-то пойдет не так, с помощью stubbing вполне может быть «nil». – Shadwell

0

Похоже, что ваш макет немного смущен; Он издевается над объектом User (но переменная экземпляра, которую вы используете, называется @user_session), а затем завершает метод #record для этого пользователя.

Кроме того, вы издеваетесь над методом current_user на контроллере UserSession, когда он определен на ApplicationController.

Что вы пытаетесь утверждать в своем тесте, так это то, что пользователь должен войти в систему, чтобы получить доступ к индексной странице Home #. В этом тесте вы не должны фокусироваться на объекте UserSession - это не так важно. Что такое is Важным является то, что если система распознает, что объект пользователя был извлечен и идентифицирован как «current_user», им должно быть разрешено получить доступ к странице.

Следующая спецификация может работать для вас:

class HomeControllerTest < ActionController::TestCase 
    context "on GET to index" do 
    setup do 
     activate_authlogic 
     @user = Factory.build(:user) 
     login_as_user(@user) 

     @controller.should_receive(:current_user).and_return(@user) 

     get :index 
    end 

    should respond_with :success 
    end 

    def login_as_user(user = Factory.build(:user)) 
    @controller.stubs(:current_user).returns(user) 
    end 
end 

Я использую @controller переменные, ActionController :: TestCase делает доступным для вас. Он представляет собой экземпляр текущего тестируемого контроллера.

Важно отметить, что - за исключением строки 4 - этот тест теперь не заботится о том, что вы используете для обеспечения функций аутентификации. Пока ваше приложение определяет метод current_user, который возвращает объект User или nil, вы можете использовать AuthLogic, Devise или любое другое решение, и ваш тест будет продолжать работать, как вы могли ожидать.

0

Я использую RSpec, но имел насмешливые проблемы, которые могут быть связаны. Причина в том, что current_user_session.record - deprecated в пользу current_user_session.user. Устаревший метод по-прежнему находится в проекте примера authlogic, а также в Railscast 160, и он может работать в коде, но вызывает проблемы при издевательстве с UserSession.