Как я могу использовать фиктивные модели в спецификациях контроллера AuthLogic? - PullRequest
4 голосов
/ 22 июня 2009

Я пытаюсь написать спецификации для контроллера без использования осветителей (вместо этого используют фиктивные модели). Этот контроллер требует, чтобы пользователь вошел в систему, для чего я использую AuthLogic , следуя рекомендациям автора .

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

Все эти примеры терпят неудачу в строке UserSession.create(...), сообщая об эффекте:

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

Я не уверен, как решить эту проблему; насмешка с :changed? => false уместна?

Ответы [ 4 ]

6 голосов
/ 23 июня 2009

Iain опубликовал решение для использования фиктивных объектов с AuthLogic . Перефразируя, следующие помощники идут в 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

Я включил это в свои спецификации и обнаружил, что это именно то, на что я надеялся. У меня есть рабочие спецификации контроллера, в которых используются модели для вошедшего в систему пользователя, поэтому теперь они не ломаются, когда я добавляю поле в User. Пример использования Iain в спецификации:

describe SecretsController do
  before { login }
  it "should be very very secret!"
end

P.S. Я ненавижу отвечать на свой вопрос, но это тот ответ, который я искал; Я просто не нашел это достаточно рано.

1 голос
/ 25 марта 2011

В Rails 3 это моделирование UserSession больше не работает, так как UserSession AuthLogic не является экземпляром ActiveRecord :: Base. Исправление, которое работает для меня:

class UserSession < Authlogic::Session::Base
  extend ActiveModel::Naming
end
1 голос
/ 22 июня 2009

Authlogic ожидает, что запись будет действовать как активный экземпляр записи. Вы можете использовать настоящий экземпляр или макет, но если вы используете макет / заглушку, вы должны быть уверены, что он отвечает на все методы, требуемые Authlogic.

Я бы предложил использовать реальный объект активной записи вместо макета. Если вы не хотите использовать прибор, вы можете использовать Фабрику.

Последний вариант - передать макет, который отвечает на любые методы (это можно легко сделать с помощью method_missing). Проблема с этим решением заключается в том, что вы заранее не знаете, какое значение должно возвращать какой-либо конкретный вызов метода.

Да, вы можете передать ложь, но это не совсем решение. Потребуется вручную попробовать / добавить значение по умолчанию, пока вы не найдете фиктивный объект, отвечающий на все запросы Authlogic. Но это потребует от вас постоянного следования authlogic для любых внутренних изменений для исправления неотвеченных вызовов на вашу заглушку.

0 голосов
/ 22 июня 2009

Я обнаружил, что насмешливые аутентичные объекты были трудными, и в конце концов я отказался от насмешек. Вместо этого я теперь использую подход генераторов, использующий object daddy . Мои функциональные тесты теперь намного счастливее. Кстати, должен + object_daddy абсолютно потрясающий. Транзакционные контексты Ifa гарантируют, что моя тестовая база данных останется чистой, и мне не нужно будет сначала насмехаться над простыми объектами activerecord

...