【发布时间】:2010-10-16 04:46:34
【问题描述】:
我继承了一个 Rails 2.2.2 应用程序,该应用程序将用户上传的图像存储在 Amazon S3 上。基于 attachment_fu 的 Photo 模型提供了一个 rotate 方法,该方法使用 open-uri 从 S3 中检索图像并使用 MiniMagick 执行旋转。
rotate 方法包含这一行来检索与 MiniMagick 一起使用的图像:
temp_image = MiniMagick::Image.from_file(open(self.public_filename).path)
self.public_filename 返回类似
http://s3.amazonaws.com/bucketname/photos/98/photo.jpg
检索图像并旋转它在生产和开发中运行的应用程序中工作得很好。但是,单元测试失败了
TypeError: can't convert nil into String
/Users/santry/Development/totspot/vendor/gems/mini_magick-1.2.3/lib/mini_magick.rb:34:in `initialize'
/Users/santry/Development/totspot/vendor/gems/mini_magick-1.2.3/lib/mini_magick.rb:34:in `open'
/Users/santry/Development/totspot/vendor/gems/mini_magick-1.2.3/lib/mini_magick.rb:34:in `from_file'
原因是在单元测试的上下文中调用模型方法时,open(self.public_filename) 正在返回一个包含图像数据的StringIO 对象。此对象上的 path 方法返回 nil 和 MiniMagick::Image.from_file 爆炸。
当从PhotosController 调用这个完全相同的模型方法时,open(self.public_filename) 返回一个绑定到名为/tmp/open-uri7378-0 的文件的FileIO 实例,并且该文件包含图像数据。
想必是测试和开发环境的一些差异,我在开发环境下启动了控制台。但就像在单元测试中一样,open('http://...') 返回了 StringIO,不是 FileIO。
我已经通过 open-uri 和所有相关的特定于应用程序的代码进行了跟踪,找不到任何差异的原因。
【问题讨论】:
标签: ruby-on-rails ruby amazon-s3 imagemagick open-uri