如何在测试环境中通过 URL 访问 ActiveStorage 对象? [英] How can I access an ActiveStorage object via URL in a test environment?

查看:34
本文介绍了如何在测试环境中通过 URL 访问 ActiveStorage 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个带有 ActiveStorage 附件的模型

Given a model that has an ActiveStorage attachment

class MyObject
  has_one_attached :avatar
end

在开发环境中,我能够将头像检索为 StringIO 对象.

In a dev environment I am able to retrive the avatar as a StringIO object.

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) 返回

When I attempt to do the same think in a test environment, open(version_url) returns

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

有没有人在测试中成功下载过 activestorage 附件?我应该如何配置测试环境来实现这一点?

Has anyone managed to successfully download activestorage attachments within a test? How should I configure the test environment to achieve this?

我的测试环境已经有

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 附件生成指向应用程序的 URL.应用程序 URL 端点然后重定向到真实文件.这将文件的物理位置与 URL 分离,并提供对镜像等功能有用的间接性.

Stored files are accessed through the Rails application server

Active Storage attachments generate URLs that point to the application. The application URL endpoint then redirects to the real file. This decouples the physical location of the file from the URL and provides indirection which is useful for features such as mirroring.

这也意味着为了使用生成的 URL 访问文件,Rails 应用程序服务器必须正在运行...

This also means that in order to access a file using its generated URL, a Rails application server must be running...

Rails 测试套件在运行测试时不会启动服务器.测试通常不需要一个即可运行.

The Rails test suite does not start up a server when running the tests. The tests typically don’t need one in order to run.

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

发生此错误是因为 open 调用尝试在服务器位置 localhost:3000 请求文件.因为没有服务器在运行,所以它失败了.

This error occurs because the open call tries to request the file at the server location localhost:3000. Because there’s no server running, it fails.

即使您启动了开发服务器,它仍然会失败,因为 Active Storage AttachmentBlob 记录存储在测试数据库中,而不是开发数据库中.

Even if you start up a development server, it will still fail because the Active Storage Attachment and Blob records are stored in the test database, not the development database.

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

In order to get access to a file or variant in your test suite, you need to bypass the application server and get a direct path to the file on disk.

Active Storage 测试套件源代码向我们展示了如何执行此操作:

The Active Storage test suite source code shows us how to do this:

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

查看源代码

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

This will return a file path (on disk) which you can then open using File.open.

在上面的例子中,改变

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

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

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

如果您正在测试使用 HTTP 访问文件的代码,最好的做法是对网络调用进行存根以完全避免它.

Use stubs to avoid network requests in the test suite

If you are testing code which accesses files using HTTP, it’s best practice to stub the network call to avoid it altogether.

这里有一些很好的例子来说明如何在 RSpec 中执行此操作:
RSpec 如何打开存根?

There’s some good examples of how to do this in RSpec here:
RSpec how to stub open?

这篇关于如何在测试环境中通过 URL 访问 ActiveStorage 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆