存储的文件通过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