0

我在以下模型上运行 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

具体来说,我正在尝试测试创建路线。从我的控制器:

def create
    @sound = Sound.create( sound_params )
    redirect_to sound_url(@sound)
end

private

def sound_params
   params.require(:sound).permit(
     :sound_file,
     :sound_name,
     :description,
     :location)
end

这是我第一次在sounds_controller_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)>'

奇怪的是,我认为“54”以某种方式连接到此文件路径:/Users/christopherspears/wdi/HearHere/public/system/sounds/sound_files/000/000/054/original/83746_braffe2_pen-writing.wav

一位同事建议我只需将带有 Sound 参数的哈希传递给测试:

describe "POST #create" do 
    it 'creates a new sound' do 
      tester_hash = {:sound_name => 'test',
                     :sound_file =>  File.open('/Users/christopherspears/wdi/83746__braffe2__pen-writing.wav')}
    post :create, sound: tester_hash
    expect(Sound.last.sound_name).to eq(tester_hash[:sound_name])
   end
end

不幸的是,这带来了另一个错误:

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)>'

我认为我在路线上没有做任何不寻常的事情:

get 'sounds/:id/download' => 'sounds#download', :as => :download
resources :sounds

有什么建议吗?似乎使用 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: 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)>'

不知道是什么原因造成的...

4

1 回答 1

0

post期望其参数是nil哈希或字符串,根据以下(取自https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/test_case.rb),这解释了为什么您的第一种方法没用。

  # 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

至于您的第二种方法,我预计它会失败,因为 Paperclip 预计将成为https://stackoverflow.com/a/11108270/1008891中讨论:sound_file的实例ActionDispatch::Http::UploadedFile

于 2013-11-14T18:51:30.003 回答