ActionDispatch :: Http :: UploadedFile.content_type未在Rspec测试中初始化
背景 :我有一个带有cover_file
属性的Book
模型,该属性通过我的一个Rails控制器使用上传的文件进行设置。 我正在使用Rails v4.0.4。
目标 :我想测试只保存具有特定内容类型的文件。 我计划使用ActionDispatch::Http:UploadedFile
创建Rspec测试示例ActionDispatch::Http:UploadedFile
使用不同的content_type
属性设置ActionDispatch::Http:UploadedFile
对象。
问题 :当我使用content_type
初始化一个新的ActionDispatch::Http::UploadedFile
时,似乎没有设置(请参阅下面的test&output确认它是nil)。 似乎我只能在初始化UploadedFile之后用setter设置它。 我没有在文档中看到任何提及这种行为,也没有在SO上找到类似的问答,所以我很感激任何人帮助确定我做错了什么。 谢谢!
代码 :
describe Book do let(:book) {FactoryGirl.build(:book)} describe "Save" do context "with valid data" do before do cover_image = File.new(Rails.root + 'spec/fixtures/images/cover_valid.jpg') book.cover_file = ActionDispatch::Http::UploadedFile.new(tempfile: cover_image, filename: File.basename(cover_image), content_type: "image/jpeg") puts book.cover_file.content_type.nil? book.cover_file.content_type = "image/jpeg" puts book.cover_file.content_type end specify{expect(book.save).to be_true} end end end
输出 :
true image/jpeg
我查看了UploadedFile
类的Rails源文件,我发现了这个问题。 例如,对于@content_type属性,当getter和setter命名为expected( .content_type
)时, initialize
方法在options散列中查找名为type
的属性。 @original_filename也会发生同样的事情; initialize查找filename
而不是original_filename
。 这似乎是自Rails 3代码库以来的情况。
所以,如果我将上面的代码更改为以下内容,一切都按预期工作:
book.cover_file = ActionDispatch::Http::UploadedFile.new(tempfile: cover_image, filename: File.basename(cover_image), type: "image/jpeg")
rails / actionpack / lib / action_dispatch / http / upload.rb的相关部分……
class UploadedFile # The basename of the file in the client. attr_accessor :original_filename # A string with the MIME type of the file. attr_accessor :content_type # A +Tempfile+ object with the actual uploaded file. Note that some of # its interface is available directly. attr_accessor :tempfile alias :to_io :tempfile # A string with the headers of the multipart request. attr_accessor :headers def initialize(hash) # :nodoc: @tempfile = hash[:tempfile] raise(ArgumentError, ':tempfile is required') unless @tempfile @original_filename = encode_filename(hash[:filename]) @content_type = hash[:type] @headers = hash[:head] end