如何在测试环境中通过 URL 访问 ActiveStorage 对象?
How can I access an ActiveStorage object via URL in a test environment?
给定一个具有 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)
returns
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") %>
通过 Rails 应用程序服务器访问存储的文件
Active Storage 附件生成指向应用程序的 URLs。应用程序 URL 端点然后重定向到真实文件。这将文件的物理位置与 URL 分离,并提供对镜像等功能有用的间接访问。
这也意味着为了使用其生成的 URL 访问文件,Rails 应用程序服务器必须 运行ning...
服务器没有运行测试环境
Rails 测试套件在 运行 测试时不会启动服务器。这些测试通常不需要为了 运行。
Errno::ECONNREFUSED Exception: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)
发生此错误是因为 open
调用试图在服务器位置 localhost:3000
请求文件。因为没有服务器 运行ning,所以它失败了。
即使启动开发服务器,它仍然会失败,因为Active Storage Attachment
和Blob
记录存储在测试数据库中,而不是开发数据库中。
绕过应用服务器并直接获取文件路径
为了访问测试套件中的文件或变体,您需要绕过应用程序服务器并获得磁盘上文件的直接路径。
Active Storage 测试套件源代码向我们展示了如何执行此操作:
blob_or_variant.service.send(:path_for, blob_or_variant.key)
这将 return 一个文件路径(在磁盘上),然后您可以使用 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 how to stub open?
给定一个具有 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)
returns
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") %>
通过 Rails 应用程序服务器访问存储的文件
Active Storage 附件生成指向应用程序的 URLs。应用程序 URL 端点然后重定向到真实文件。这将文件的物理位置与 URL 分离,并提供对镜像等功能有用的间接访问。
这也意味着为了使用其生成的 URL 访问文件,Rails 应用程序服务器必须 运行ning...
服务器没有运行测试环境
Rails 测试套件在 运行 测试时不会启动服务器。这些测试通常不需要为了 运行。
Errno::ECONNREFUSED Exception: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)
发生此错误是因为 open
调用试图在服务器位置 localhost:3000
请求文件。因为没有服务器 运行ning,所以它失败了。
即使启动开发服务器,它仍然会失败,因为Active Storage Attachment
和Blob
记录存储在测试数据库中,而不是开发数据库中。
绕过应用服务器并直接获取文件路径
为了访问测试套件中的文件或变体,您需要绕过应用程序服务器并获得磁盘上文件的直接路径。
Active Storage 测试套件源代码向我们展示了如何执行此操作:
blob_or_variant.service.send(:path_for, blob_or_variant.key)
这将 return 一个文件路径(在磁盘上),然后您可以使用 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 how to stub open?