我在以下型号上运行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)>'
不确定是什么导致这个......
答案 0 :(得分: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希望:sound_file
成为ActionDispatch::Http::UploadedFile
的实例,如https://stackoverflow.com/a/11108270/1008891