我继承了一个 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)
返回一个FileIO
与名为 eg 的文件绑定的实例,/tmp/open-uri7378-0
该文件包含图像数据。
想着一定是测试和开发环境的差异,我在开发环境下启动了控制台。但就像在单元测试中一样,open('http://...')
返回 a StringIO
,而不是a FileIO
。
我已经通过 open-uri 和所有相关的特定于应用程序的代码追踪了我的方式,并且找不到任何差异的原因。