Documents クラスをテストしようとしています。次のファクトリを定義しました。
require 'factory_girl'
FactoryGirl.define do
factory :document do
user_id '6315'
name 'Test doc'
description 'W9'
filename 'test_doc.pdf'
filetype 'file'
filesize 500
end
factory :invalid_doc, parent: :document do
filesize 5242900
end
end
次のヘルパー メソッドを使用して、テスト内の適切な属性にアクセスします。
def build_attributes(*args)
attrs = FactoryGirl.build(*args).attributes
attrs.delete_if do |k, v|
["id", "created_at", "updated_at"].member?(k)
end
paramify_values(attrs)
end
私が実行する各テストの前に:
before(:each) do
login_as_admin
@doc = @user.documents.create(FactoryGirl.attributes_for(:document))
end
@user はlogin_as_admin
マクロで設定されます。私のテストでは、これを実行しています:
describe 'POST #create' do
it "should create a new document" do
expect{
post :create, document: build_attributes(:document, user_id: @doc.user_id)
}.to change(Document,:count).by(1)
end
it "should find the right user" do
post :create, document: build_attributes(:document, user_id: @doc.user_id)
assigns(:user).should eq(@user)
end
# some other tests...
end
前者のテストはこの記事で提案されたもので、後者はちょうど私が起こるべきだと思うものです。コントローラーのアクションは、インスタンスに次のものを割り当てています。
@user = User.find(document[:user_id])
だから、かなり標準的です。ただし、これらのテストはどちらも同じエラーをスローします。
Failure/Error: post :create, document: build_attributes(:document, user_id: @doc.user_id)
NoMethodError:
undefined method `original_filename' for nil:NilClass
しかし、私はそのメソッドを明示的に呼び出すことはありません。FactoryGirl が呼び出しているものですか? モデルは次のように記述されます。
attr_accessible :description, :filename, :filesize, :filetype, :name, :user_id
は:filename
単なる文字列です。ここで何がうまくいかないのでしょうか?私はファイルをアップロードするためにペーパークリップを使用していませんfile_field
。パスを取得し、ファイルをコントローラー内の運用サーバーに保存しますが、このメソッドを呼び出すことはありません。
編集:
実際のコントローラーの説明が役立つと思います笑
def create
uploaded_file = params[:document][:file]
document = params[:document]
document.delete(:file)
@user = User.find(document[:user_id])
filepath = Rails.root.join('documents', @user.company_id.to_s, @user.id.to_s, uploaded_file.original_filename)
%x[ mkdir #{Rails.root.join('documents', @user.company_id.to_s)} ]
%x[ mkdir #{Rails.root.join('documents', @user.company_id.to_s, @user.id.to_s)} ]
File.open(filepath, 'wb') do |file|
file.write(uploaded_file.read)
end
document[:filesize]= File.size(filepath)
document[:filetype]= File.ftype(filepath)
document[:filename] = uploaded_file.original_filename
d =Document.new(document)
d.save
redirect_to :action => 'show', :id => user.id
end
この方法には多くの問題があると確信していることを覚えておいてください。私はそれをリファクタリングしてテストしようとしています。今のところ、私がやろうとしているのは、この最初の問題を乗り越えることだけです。original_filename
メソッドはどこかで呼び出されており、自分で定義していません。なぜ/どこで誰が見ることができますか?