Ruby on rails 使用Rspec测试控制器(模型已验证附件的存在)

Ruby on rails 使用Rspec测试控制器(模型已验证附件的存在),ruby-on-rails,rspec,Ruby On Rails,Rspec,我在以下型号上运行rspec测试时遇到问题: class Sound < ActiveRecord::Base belongs_to :user # for paperclip has_attached_file :sound_file # do not create a sound unless a sound file # is present validates_attachment_presence :sound_file end 以下是我在sounds

我在以下型号上运行rspec测试时遇到问题:

class Sound < ActiveRecord::Base
  belongs_to :user

  # for paperclip
  has_attached_file :sound_file

  # do not create a sound unless a sound file
  # is present
 validates_attachment_presence :sound_file
end
以下是我在sounds\u controller\u spec.rb文件中首次编写的内容:

   describe "POST #create" do

     it 'creates a new sound' do 
       tester_sound = FactoryGirl.create(:sound,
                                     :sound_name => 'test',
                                     :sound_file => File.open('/Users/christopherspears/wdi/83746__braffe2__pen-writing.wav'))
       post :create, sound: tester_sound
       expect(Sound.last.sound_name).to eq(tester_sound[:sound_name])
     end
  end
我收到了以下错误消息:

  1) SoundsController POST #create creates a new sound
     Failure/Error: post :create, sound: tester_sound
     NoMethodError:
       undefined method `permit' for "54":String
       # ./app/controllers/sounds_controller.rb:53:in `sound_params'
       # ./app/controllers/sounds_controller.rb:16:in `create'
       # ./spec/controllers/sounds_controller_spec.rb:39:in `block (3 levels) in <top     (required)>'
不幸的是,这带来了另一个错误:

Failures:

  1) SoundsController POST #create creates a new sound
     Failure/Error: post :create, sound: tester_hash
     Paperclip::AdapterRegistry::NoHandlerError:
       No handler found for "#<File:0x007ff603de0868>"
     # ./app/controllers/sounds_controller.rb:16:in `create'
    # ./spec/controllers/sounds_controller_spec.rb:48:in `block (3 levels) in <top (required)>'
有什么建议吗?似乎用validates_attachment_presence测试模型的控制器将是一个挑战

更新

我现在正在尝试一种不同的方法

let(:valid_attributes) { { "sound_name" => "test", "sound_file" => File.new } }
let(:valid_session) { {} }

describe "POST #create" do 
    it 'creates a new sound' do
      sound = FactoryGirl.create(:sound => valid_attributes)
      expect { sound.sound_name }.to eq("test")
    end
end
好吧,至少我得到了不同的错误信息:

  1) SoundsController POST #create creates a new sound
     Failure/Error: post :create, sound: tester_sound
     NoMethodError:
       undefined method `permit' for "54":String
       # ./app/controllers/sounds_controller.rb:53:in `sound_params'
       # ./app/controllers/sounds_controller.rb:16:in `create'
       # ./spec/controllers/sounds_controller_spec.rb:39:in `block (3 levels) in <top     (required)>'
失败:

  1) SoundsController POST #create creates a new sound
     Failure/Error: let(:valid_attributes) { { "sound_name" => "test", "sound_file" => File.new } }
     ArgumentError:
       wrong number of arguments (0 for 1..3)
       # ./spec/controllers/sounds_controller_spec.rb:4:in `initialize'
       # ./spec/controllers/sounds_controller_spec.rb:4:in `new'
       # ./spec/controllers/sounds_controller_spec.rb:4:in `block (2 levels) in <top (required)>'
       # ./spec/controllers/sounds_controller_spec.rb:38:in `block (3 levels) in <top (required)>'
1)声音控制器POST#创建新声音
失败/错误:let(:valid_attributes){{{“sound_name”=>“test”,“sound_file”=>file.new}
参数错误:
参数数目错误(0表示1..3)
#./spec/controllers/sounds\u controller\u spec.rb:4:in'initialize'
#./spec/controllers/sounds\u controller\u spec.rb:4:in'new'
#./spec/controllers/sounds\u controller\u spec.rb:4:in'block(2层)in'
#./spec/controllers/sounds\u controller\u spec.rb:38:in'block(3层)in'

不确定是什么导致了这种情况…

post
期望其参数为
nil
一个散列或字符串,如下所示(取自),这解释了第一种方法不起作用的原因

  # Simulate a GET request with the given parameters.
  #
  # - +action+: The controller action to call.
  # - +parameters+: The HTTP parameters that you want to pass. This may
  #   be +nil+, a hash, or a string that is appropriately encoded
  #   (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
  # - +session+: A hash of parameters to store in the session. This may be +nil+.
  # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
  #
  # You can also simulate POST, PATCH, PUT, DELETE, HEAD, and OPTIONS requests with
  # +post+, +patch+, +put+, +delete+, +head+, and +options+.
  #
  # Note that the request method is not verified. The different methods are
  # available to make the tests more expressive.
  def get(action, *args)
    process(action, "GET", *args)
  end

  # Simulate a POST request with the given parameters and set/volley the response.
  # See +get+ for more details.
  def post(action, *args)
    process(action, "POST", *args)
  end
#使用给定参数模拟GET请求。
#
#-+操作+:要调用的控制器操作。
#-+参数+:要传递的HTTP参数。今年五月
#be+nil+、哈希或经过适当编码的字符串
#(应用程序/x-www-form-urlencoded或多部分/表单数据)。
#-+会话+:要存储在会话中的参数散列。这可能是+nil+。
#-+闪存+:存储在闪存中的参数散列。这可能是+nil+。
#
#您还可以使用模拟POST、PATCH、PUT、DELETE、HEAD和OPTIONS请求
#+post+、+patch+、+put+、+delete+、+head+和+options+。
#
#请注意,请求方法未经验证。不同的方法是
#可用于使测试更具表现力。
def get(操作,*args)
流程(操作,“获取”、*args)
结束
#使用给定参数模拟POST请求并设置/截取响应。
#有关更多详细信息,请参阅+get+。
def post(操作,*args)
过程(操作,“POST”、*参数)
结束

至于您的第二种方法,我认为它会失败,因为曲别针希望
:sound_file
成为
ActionDispatch::Http::UploadedFile
的一个实例,如

Great!谢谢关于在Rspec中模拟ActionDispatch::Http::UploadedFile实例有什么建议吗?我一直试图在网上找到一些东西,但没有成功。
  1) SoundsController POST #create creates a new sound
     Failure/Error: let(:valid_attributes) { { "sound_name" => "test", "sound_file" => File.new } }
     ArgumentError:
       wrong number of arguments (0 for 1..3)
       # ./spec/controllers/sounds_controller_spec.rb:4:in `initialize'
       # ./spec/controllers/sounds_controller_spec.rb:4:in `new'
       # ./spec/controllers/sounds_controller_spec.rb:4:in `block (2 levels) in <top (required)>'
       # ./spec/controllers/sounds_controller_spec.rb:38:in `block (3 levels) in <top (required)>'
  # Simulate a GET request with the given parameters.
  #
  # - +action+: The controller action to call.
  # - +parameters+: The HTTP parameters that you want to pass. This may
  #   be +nil+, a hash, or a string that is appropriately encoded
  #   (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
  # - +session+: A hash of parameters to store in the session. This may be +nil+.
  # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
  #
  # You can also simulate POST, PATCH, PUT, DELETE, HEAD, and OPTIONS requests with
  # +post+, +patch+, +put+, +delete+, +head+, and +options+.
  #
  # Note that the request method is not verified. The different methods are
  # available to make the tests more expressive.
  def get(action, *args)
    process(action, "GET", *args)
  end

  # Simulate a POST request with the given parameters and set/volley the response.
  # See +get+ for more details.
  def post(action, *args)
    process(action, "POST", *args)
  end