如何在测试环境中通过 URL 访问 ActiveStorage 对象?

2024-05-12

给定一个具有 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"}

我忽略了什么?

EDIT

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

存储的文件通过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 StorageAttachment and Blob记录存储在测试数据库中,而不是开发数据库中。

绕过应用程序服务器并直接获取文件的路径

为了访问测试套件中的文件或变体,您需要绕过应用程序服务器并获取磁盘上文件的直接路径。

Active Storage 测试套件源代码向我们展示了如何做到这一点:

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

查看源代码 https://github.com/rails/rails/blob/65bf046fd1c05405591b940e3b3cd718ca1edba1/activestorage/test/test_helper.rb#L74

这将返回一个文件路径(在磁盘上),然后您可以使用它打开该路径File.open.

修复上面的示例

在上面的例子中,改变

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

to

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

使用存根来避免测试套件中的网络请求

如果您正在测试使用 HTTP 访问文件的代码,最佳实践是对网络调用进行存根以完全避免这种情况。

这里有一些关于如何在 RSpec 中执行此操作的好示例:
RSpec如何存根打开? https://stackoverflow.com/questions/3603256/rspec-how-to-stub-open

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在测试环境中通过 URL 访问 ActiveStorage 对象? 的相关文章

  • Ruby/Rails - 访问“查找”表而不对其进行建模?

    这是针对 Ruby on Rails 3 0 x 项目的 我有一个 查找 表 其中包含来自供应商的数据 当我从其他来源导入数据时 我想检查此表 加入 SKU 以获取额外数据 在我的应用程序中为该表创建模型对我来说似乎不合适 我的应用程序永远
  • Rails - 格式日期字段

    如何设置 date field 的日期格式样式 我得到了以下表格 这是为日期字段呈现以下 HTML
  • Rails 引擎 - 简单的可能引擎(1)添加模型并(2)在包含类中添加关联

    我正在尝试编写我的第一个引擎 但在以下场景中遇到问题 在主机应用程序中 我将拥有具有名称的用户模型 这是保证的 因此在引擎中我可以引用用户类而不是某种程度的间接 在引擎中 我将有一个帖子模型 并且需要在帖子模型和包含应用程序中的用户模型之间
  • 将 gmaps4rails 与 https/SSL 结合使用

    我是 gmaps4rails 的忠实粉丝 它使向我们的网络应用程序添加地图变得非常容易 我现在遇到的唯一问题是 如果您在 https 页面上使用它 则会收到有关混合内容的安全警告 谷歌地图API确实支持https 所以我认为这只是将脚本引用
  • Rails:如何重新启动 sidekiq?

    我正在使用 sidekiq gem 在后台运行 API 调用 我在守护进程中运行 sidekiq 如下所示 bundle exec sidekiq d 现在我对我的方法做了一些更改 所以我想重新启动 sidekiq 我尝试使用以下命令杀死
  • 在运行时在 Rails 中向模型添加列(无需附加表)

    我试图让我的网络应用程序的管理员能够向模型添加一些新字段 该模型称为 Artwork 我想在运行时添加一个 test column 列 我只是在测试 所以我添加了一个简单的链接来做到这一点 它当然是参数化的 我设法通过迁移来做到这一点 de
  • 使用 FactoryGirl 测试简单的 STI

    我有一个类 它是其他一些专门处理该行为的类的基础 class Task lt ActiveRecord Base attr accessible type name command validates presence of type na
  • 具有预加载功能的 ActiveRecord::Calculations 是否会进行多个数据库查询?

    我的困惑源于这个问题 https stackoverflow com q 19462024 1860929 其中 OP 的模型如下 class Quote lt ActiveRecord Base has many items def ca
  • Rails 中的命名空间模型生成 NameError:未初始化的常量

    我有一个这样的文件夹结构 app models bar foo rb connection rb foo rb connection rb是一个用于连接到另一个数据库的 抽象类 所以 class Bar Connection lt Acti
  • 为什么将 Backbone.js 与 Rails 结合使用? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 test/fixtures/user.yml 中创建可用于 Devise 4 中集成测试的测试用户?

    从下面的代码中可以看到 我已经创建了一个用户users yml 包括设备的集成测试助手test helper rb 这就是为什么我能够使用sign in方法 基于设计的自述文件 https github com plataformatec
  • 如何将 current_user 传递给 Sidekiq 的 Worker

    我正在努力通过current user or User find 1 到工作模块 但在 sidekiq 的仪表板中出现错误 localhost 3000 sidekiq retries NoMethodError 未定义方法 支持 字符串
  • 使用 Ruby on Rails 的多个应用程序

    单个 Ruby on Rails 安装是否可以拥有多个共享通用模型的应用程序 例如 我想要一个前端应用程序以及后端管理控制台 但两者共享相同的模型 这类似于 Symfony 在 PHP 中的工作方式 提前致谢 拥有管理面板的最简单方法是使用
  • 如何通过迁移向现有索引添加“唯一”约束

    我怎样才能添加unique true对 Rails 数据库中已有索引的约束 我尝试通过以下方式迁移 def change add index editabilities user id list id unique true end 但迁移
  • 前面的冒号:YAML 语法

    我目前在项目中使用 Sidekiq 并且有以下 YAML 配置文件 concurrency 5 pidfile tmp pids sidekiq pid logfile log sidekiq log staging concurrency
  • 如何停止 Heroku 服务器?

    我有一个托管在 heroku 上的临时服务器 我只想将其关闭 但不想破坏该应用程序 我该怎么做 我是否有类似 heroku stop 之类的命令 例如 heroku restart 来重新启动 OR 有没有办法让服务器在超过 750 小时免
  • 没有路线匹配... Rails Engine

    所以我不断收到错误 No route matches action gt create controller gt xaaron api keys 测试中抛出的是 it should not create an api key for th
  • Rspec:测试救援

    尝试测试我的函数是否能够正确地从异常中解救 更改参数 文件名 然后重试一次 我可以让函数接收第一次尝试 但无法让它接收第二次尝试 控制器 begin video get video video id rescue matches video
  • Rails 3.1 中的嵌套表单

    我在嵌套表单方面遇到问题 rails 3 1 在应该渲染 fields for 块时不渲染 fields for 块 例如 在编辑现有记录时 由于我对自己的英语不够自信 我制作了一个小示例应用程序 新行动 def new manga Man
  • Rails:统计用户未读通知的数量

    我目前有一个处理用户活动通知系统的活动模型 当发生某些操作 例如创建新文章 时 活动观察者会创建一个新活动 现在我想记录当前用户尚未看到的这些活动通知中有多少 类似于 facebook 上的通知宝石 每次用户单击通知链接时 数字应重置为 0

随机推荐