15

コントローラーの 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)>'

会社コントローラー

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/company_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    
4

5 に答える 5

25

メソッドがテストケースの対象である場合、メソッドをスタブしたくない

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

それが役に立てば幸い。

于 2013-07-29T08:07:55.410 に答える
6

コントローラーをテストしている場合は、コントローラーに直接アクセスできます。

controller.stub(:message) { 'this is the value to return' }
于 2014-08-28T00:07:52.447 に答える
6

コードのテストが困難な場合、通常はコードが複雑であることが原因です。

このコードを次のようにリファクタリングする必要があります。

  • 検証ロジックを、Facebook での企業検証の単一の責任を持つ新しい「サービス クラス」に移動します。
  • これにより、検証機能が Web レイヤーから独立し、テストがはるかに簡単になります。
  • このコードを分離してテストするサービス クラスの仕様を作成します (コントローラーなし)。
  • ロジックのコントローラーをクリーンアップする - コントローラー内にロジックを入れたくない (経験則: ネストの最大レベルは 1 レベル)
  • コントローラーの仕様も簡単になります

コントローラーのコードは次のようになります。

def create
  company = Company.new(params[:company])
  verified = FbCompanyVerifier.new.verify(company)

  if verified and company.save
    # success logic
  else
    # fail logic
  end
end
于 2013-07-29T09:55:06.087 に答える