我继承了一个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)
Run Code Online (Sandbox Code Playgroud)
self.public_filename 返回类似的东西
http://s3.amazonaws.com/bucketname/photos/98/photo.jpg
Run Code Online (Sandbox Code Playgroud)
检索图像并旋转它在生产和开发中正在运行的应用程序中工作正常.但是,单元测试失败了
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'
Run Code Online (Sandbox Code Playgroud)
原因是当在单元测试的上下文中调用模型方法时,open(self.public_filename)返回StringIO包含图像数据的对象.path此对象上的方法返回nil并MiniMagick::Image.from_file爆炸.
当从该调用这个相同的模型方法时PhotosController,open(self.public_filename)返回FileIO绑定到例如名为的文件的实例,/tmp/open-uri7378-0并且该文件包含图像数据.
考虑原因必须是测试和开发之间的一些环境差异,我在开发环境下启动了控制台.但正如在单元测试中,open('http://...')返回一个StringIO,而不是一个FileIO.
我已经通过open-uri和所有相关的应用程序特定代码进行了跟踪,并且没有找到差异的理由.