Как протестировать cookies.permanent.signed в Rails 3

У меня есть действие в каком-то контроллере, которое устанавливает некоторое значение в постоянном подписанном файле cookie, например:


def some_action
    cookies.permanent.signed[:cookie_name] = "somevalue"
end

И в каком-то функциональном тесте я пытаюсь проверить, правильно ли был установлен файл cookie, предъявляя иск:


test "test cookies" do
    assert_equal "somevalue", cookies.permanent.signed[:cookie_name]
end


Однако, когда я запускаю тест, я получаю следующую ошибку:


NoMethodError: undefined method `permanent' for #

Если я попробую только:


test "test cookies" do
    assert_equal "somevalue", cookies.signed[:cookie_name]
end


Я получил:


NoMethodError: undefined method `signed' for #

Как протестировать подписанные файлы cookie в Rails 3?


person Joao Pereira    schedule 12.02.2011    source источник


Ответы (5)


Я столкнулся с этим вопросом, когда искал решение аналогичной проблемы в Google, поэтому я опубликую здесь. Я надеялся установить подписанный файл cookie в Rspec перед тестированием действия контроллера. Сработало следующее:

jar = ActionDispatch::Cookies::CookieJar.build(@request)
jar.signed[:some_key] = "some value"
@request.cookies['some_key'] = jar[:some_key]
get :show ...

Обратите внимание, что следующее не сработало:

# didn't work; the controller didn't see the signed cookie
@request.cookie_jar.signed[:some_key] = "some value"
get :show ...
person balexand    schedule 18.07.2011
comment
Просто наткнулся на это, и это отлично решило мою проблему, но в качестве важного дополнения мне пришлось изменить: @request.cookies[:some_key] на: @request.cookies[some_key] - person Atiaxi; 09.09.2011
comment
Отличный балександ. Хотел бы я поставить вам 10 лайков. - person allesklar; 08.12.2011
comment
@Atiasi, используя Rails 3.2.12, и я мог бы использовать символ для доступа к @request.cookies[:some_key] = jar[:some_key] - person Gerry Shaw; 01.03.2013
comment
первоначальный вопрос был о просмотре файлов cookie ответов. не файлы cookie запроса. - person Mathieu J.; 11.02.2014
comment
Rspec объясняет строки и символы при ссылке на файлы cookie здесь: relishapp.com/ rspec/rspec-rails/docs/controller-specs/cookies - person Chris Beck; 29.12.2014

В Rails 3 ActionControlller::TestCase вы можете установить подписанные постоянные файлы cookie в объекте запроса следующим образом:

 @request.cookies.permanent.signed[:foo] = "bar"

И возвращенные подписанные файлы cookie из действия, предпринятого в контроллере, можно протестировать, выполнив следующие действия.

 test "do something" do
     get :index # or whatever
     jar = @request.cookie_jar
     jar.signed[:foo] = "bar"
     assert_equal jar[:foo], @response.cookies['foo'] #should both be some enc of 'bar'
 end 

Обратите внимание, что нам нужно установить подписанный файл cookie jar.signed[:foo], но прочитать неподписанный файл cookie jar[:foo]. Только тогда мы получаем зашифрованное значение cookie, необходимое для сравнения в assert_equal.

person Anthony Bishopric    schedule 30.03.2011
comment
Потрясающий! Я просто использую: @request.cookie_jar.signed[:foo] = 'bar' - person Trevor Turk; 02.02.2012

Посмотрев на код Rails, который обрабатывает это, я создал для этого тестовый помощник:

  def cookies_signed(name, opts={})
    verifier = ActiveSupport::MessageVerifier.new(request.env["action_dispatch.secret_token".freeze])
    if opts[:value]
      @request.cookies[name] = verifier.generate(opts[:value])
    else
      verifier.verify(cookies[name])
    end
  end

Добавьте это в test_help.rb, затем вы можете установить подписанный файл cookie с помощью:

cookies_signed(:foo, :value => 'bar')

И прочитайте его с:

cookies_signed(:foo)

Возможно, немного хакерский, но для меня это работает.

person Roger Ertesvag    schedule 01.02.2012
comment
Хорошо сделано, я переименовал метод в #signed_cookie и добавил его в модуль для смешивания со спецификациями контроллера. см. эту суть для справки - person Kenneth Kalmer; 14.05.2012

Проблема (по крайней мере, на первый взгляд) заключается в том, что в контексте функционального теста (ActionController::TestCase) объект «cookies» является хэшем, тогда как при работе с контроллерами это ActionDispatch::Cookies:: Объект CookieJar. Поэтому нам нужно преобразовать его в объект CookieJar, чтобы мы могли использовать для него метод «signed», чтобы преобразовать его в SignedCookieJar.

Вы можете поместить следующее в свои функциональные тесты (после запроса на получение), чтобы преобразовать файлы cookie из объекта Hash в объект CookieJar.

@request.cookies.merge!(cookies)
cookies = ActionDispatch::Cookies::CookieJar.build(@request)
person Polemarch    schedule 02.03.2011
comment
У меня точно такая же проблема. Я использую тестовый модуль. Я не понимаю, как использовать ваш 2-строчный. Я пробовал разные перестановки, но ничего не получалось. Не могли бы вы привести более подробный пример того, как это использовать. - person allesklar; 03.03.2011

Проблема также заключается в ваших тестах.

Вот некоторый код и тесты, которые я использовал для TDD ситуации, когда вы хотите установить значение файла cookie путем передачи значения params в представление.

Функциональный тест:

test "reference get set in cookie when visiting the site" do
  get :index, {:reference => "121212"}
  refute_nil cookies["reference"]
end

Некоторые контроллеры:

before_filter :get_reference_code

Контроллер приложений:

def get_reference_code
  cookies.signed[:reference] ||= params[:reference]
end

Обратите внимание, что строка refute_nil, куки - это строка... это одна из причин, по которой этот тест также не прошел, это добавление символа в cookies[:reference] тесту это не понравилось, поэтому я этого не делал.

person pjammer    schedule 06.08.2011