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 
Interesting Posts