Как включить объект сеанса Rails.cache для приложения Rails во время тестов

У меня многоступенчатая форма приема.

Я сохраняю данные каждого шага в объекте Rails.cache, используя session.id в качестве ключа.

def initialize_cache
  Rails.cache.fetch(session.id) { Hash.new }
end

def add_params_to_cache
  attrs = Rails.cache.read(session.id).merge(user_profile_params)
  Rails.cache.write(session.id, attrs)
end

Это работает в режиме разработки.

Однако мои тесты терпят неудачу, потому что session.id равен нулю.

Я включил кеширование в файле среды test.rb:

  config.action_controller.perform_caching = true
  config.cache_store = :memory_store

Тем не менее, я все еще получаю ноль для session.id.

Единственное плохое решение, которое я нашел, это использовать следующий метод в контроллерах:

    def session_id
  @session_id ||= Rails.env.test? ? :test : session.id
end

Есть ли способ получить идентификатор объекта сеанса во время тестов рельсов?

Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
4
0
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы получаете session.id только тогда, когда сохраняете что-то в сеансе, иначе это nil. По первому запросу в сеансе еще ничего не хранится. После того, как ваше действие контроллера выполнено, rails сохраняет _csrf_token и, следовательно, session_id также сохраняется. Просто выньте:

<%= csrf_meta_tags %>

Из вашего макета и session.id никогда не будут инициализированы (если у вас нет другого сеанса обновления).

Идентификатор сеанса ничего особенного но вам, вероятно, следует создать свой собственный ключ для этой цели:

# it's what session id is anyway
session[:cache_id] ||= SecureRandom.hex(16)

Вы также можете сохранить что-то в сеансе, и id инициализирует:

# assuming there is no session
cookies.clear

session.id #=> nil

# any one of these will initialize session id
session.update({})
session.send(:load!)
session[:touch] = "poke"
# or this
session.destroy
session.clear

session.id #=> "cc3363adc0831258d3173f207a62dcae"

Что касается теста, он просто показывает, что session.id не является надежным источником идентификатора вашего кеша. Исправьте это в контроллере с самого начала.

class HomeController < ApplicationController
  def index
    p "this does not initialize session.id"
    p Rails.cache.fetch(session.id) { Hash.new }
    p session.id # still nil
    p
    p "this will initialize session"
    p session.update({}) # or any other way mentioned above
    p Rails.cache.fetch(session.id) { Hash.new }
    p session.id
  end
end
$ bin/rails test test/controllers/home_controller_test.rb
Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 48575

# Running:

"this does not initialize session.id"
{}
nil
"this will initialize session"
{"session_id"=>"39c1ee00e1e9214250d0bb6cfbfa68dc"}
{}
"39c1ee00e1e9214250d0bb6cfbfa68dc"
.

Finished in 0.294108s, 3.4001 runs/s, 3.4001 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

Это как зайти на страницу в первый раз. Попробуйте в окне инкогнито, session.id будет nil, но только при первом посещении. В тесте это всегда первое посещение.

Спасибо за ваш ответ @Alex. Когда я запускаю это в dev, я инициализирую session.id пустым хешем (см. мой ответ). На данный момент у меня есть идентификатор сеанса. Однако, когда я запускаю свои тесты, которые также вызывают метод инициализации, session.id равен нулю. Вот почему мне пришлось добавить Rails.env.test? ? :test : session.id, который я бы предпочел не использовать. Итак, мой вопрос остается, почему, когда я запускаю свои тесты, у меня нет значения session.id?

chell 16.01.2023 15:51

@chell см. обновление. надеюсь, что это делает его более ясным.

Alex 16.01.2023 18:21

Спасибо за то, что сделали это намного яснее. Я добавил session.update({}).to_h для инициализации сеанса, и он работает.

chell 16.01.2023 20:10

Другие вопросы по теме