Как я могу получить доступ к объекту ActiveStorage через URL в тестовой среде? - PullRequest
0 голосов
/ 29 августа 2018

Учитывая модель с вложением ActiveStorage

class MyObject
  has_one_attached :avatar
end

В среде разработчиков я могу получить аватар как объект StringIO.

obj = MyObject.new( { valid params } )
file = File.open( Rails.root.join( "spec/support/images/test_image.jpg" ))
obj.avatar.attach( io: file, filename: "test_image.jpg" )
obj.save

version = obj.avatar.variant( resize: '200x200>').processed
version_url = Rails.application.routes.url_helpers.url_for( version )
download = open(version_url)
download.class 
=> StringIO

Когда я пытаюсь сделать то же самое в тестовой среде, open(version_url) возвращает

Errno::ECONNREFUSED Exception: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)

Кому-нибудь удалось успешно загрузить вложения activestorage в рамках теста? Как мне настроить тестовую среду для достижения этой цели?

Моя тестовая среда уже имеет

config.active_storage.service = :test
Rails.application.routes.default_url_options = {host: "localhost:3000"}

Что я упустил из виду?

РЕДАКТИРОВАТЬ

#storage.yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

1 Ответ

0 голосов
/ 14 сентября 2018

Доступ к сохраненным файлам осуществляется через сервер приложений Rails

Вложения Active Storage генерируют URL, которые указывают на приложение. Конечная точка URL-адреса приложения затем перенаправляется в реальный файл. Это отделяет физическое местоположение файла от URL и обеспечивает косвенное обращение, которое полезно для таких функций, как зеркальное отображение.

Это также означает, что для доступа к файлу по его сгенерированному URL-адресу должен быть запущен сервер приложений Rails ...

Сервер не работает в тестовой среде

Набор тестов Rails не запускает сервер при выполнении тестов. Обычно тесты не нужны для запуска.

Errno::ECONNREFUSED Exception: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)

Эта ошибка возникает из-за того, что вызов open пытается запросить файл в расположении сервера localhost:3000. Поскольку не работает ни один сервер, происходит сбой.

Даже если вы запустите сервер разработки, он все равно потерпит неудачу, поскольку записи Active Storage Attachment и Blob хранятся в тестовой базе данных, а не в базе данных разработки.

Обойти сервер приложений и получить путь непосредственно к файлу

Чтобы получить доступ к файлу или варианту в вашем тестовом наборе, вам нужно обойти сервер приложений и получить прямой путь к файлу на диске.

Исходный код набора тестов Active Storage показывает, как это сделать:

blob_or_variant.service.send(:path_for, blob_or_variant.key)

Просмотр источника

Возвращает путь к файлу (на диске), который затем можно открыть с помощью File.open.

Исправление примера выше

В приведенном выше примере измените

download = open(version_url) # BAD: tries to access using HTTP

до

download = File.open( version.service.send(:path_for, version.key) )

Использование заглушек, чтобы избежать сетевых запросов в наборе тестов

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

Вот несколько хороших примеров того, как сделать это в RSpec:
RSpec как заглушка открыть?

...