コントローラのcreateメソッドにあるメソッドをスタブする方法を教えてもらえますか?このための仕様を書く必要がありますが、これらのエラーが発生しました。モデルに新しい会社レコードを作成する前に、コントローラーのcreateメソッドでvalidate_fbidメソッドを実行する必要があることを確認する必要があります。
エラー:
1) Companies new company create with valid information#validate_fbid should have correct parameters and return value
Failure/Error: CompaniesController.create.should_receive(:validates_fbid).with(company)
NoMethodError:
undefined method `create' for CompaniesController:Class
# ./spec/requests/companies_spec.rb:38:in `block (5 levels) in <top (required)>'
2) Companies new company create with valid information#validate_fbid should fbid validation passed
Failure/Error: CompaniesController.create.stub(:validates_fbid).and_return('companyid')
NoMethodError:
undefined method `create' for CompaniesController:Class
# ./spec/requests/companies_spec.rb:43:in `block (5 levels) in <top (required)>'
CompaniesController
def create
company = Company.new(params[:company])
verifyfbid = validate_fbid(company)
if verifyfbid != false
if company.fbid.downcase == verifyfbid.downcase
if company.save
@message = "New company created."
redirect_to root_path
else
@message = "Company create attempt failed. Please try again."
render 'new'
end
else
@message = "Company create attempt failed. Invalid facebook id."
render 'new'
end
else
@message = "Company create attempt failed. No such facebook id."
render 'new'
end
end
private
def validate_fbid(company)
uri = URI("http://graph.facebook.com/" + company.fbid)
data = Net::HTTP.get(uri)
username = JSON.parse(data)['username']
if username.nil?
return false
else
"#{username}"
end
end
Requests/Companies_spec.rb
context "#validate_fbid" do
#validate fbid
let(:company){ Company.new(name:'Example Company', url: 'www.company.com', fbid: 'companyid', desc: 'Company desc' )}
it "should have correct parameters and return value" do
CompaniesController.create.should_receive(:validates_fbid).with(company)
.and_return('companyid')
end
it "should fbid validation passed" do
CompaniesController.create.stub(:validates_fbid).and_return('companyid')
company.fbid.should_not be_nil
company.fbid.should == 'companyid'
company.save
expect { click_button submit }.to change(Company, :count).by(1)
end
end
テストケースの対象である場合、メソッドをスタブ化する必要はありません。
context "#validate_fbid" do
#test the function here
#don't stub
end
コントローラで作成アクションをテストするときに、「validate_fbid」をスタブ化できます
describe "post create" do
...
CompaniesController.any_instance.stub(:validates_fbid).and_return('companyid')
...
end
それが役に立てば幸い。
コードのテストが難しい場合、それは通常、複雑であるためです。
このコードは次のようにリファクタリングする必要があります。
コントローラコードは次のようになります。
def create
company = Company.new(params[:company])
verified = FbCompanyVerifier.new.verify(company)
if verified and company.save
# success logic
else
# fail logic
end
end
コントローラをテストしている場合は、コントローラに直接アクセスできます。
controller.stub(:message) { 'this is the value to return' }
Rspec 3(3.3)の推奨構文は次のとおりです。
allow_any_instance_of(CompaniesController).to receive(:validates_fbid).and_return("companyid")
または
expect_any_instance_of(CompaniesController).to receive(:validates_fbid).and_return("companyid")
ソース: https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance