2017-10-11 2 views
0

Rspecをテストして学習するのが初めてで、うまく動作しません。Rspec3コントローラでbelongs_toアソシエーションを使用してinstance_doubleを使用してテストする

(私は本Rspec3との効果的なテスト、および多くのチュートリアルを読んだことがある...またpluralsight.com)

状況は非常に簡単です。私はこの方法、companyモデルbelongs_to userを作成し、これはコードであるデをテストしたいCompaniesコントローラで:expect(Company).to receive(:new).with(company_params)

またはコントローラで:

私はテストで

を実行するときに問題があると思います: @company.user=helpers.user

コントローラー:

class CompaniesController < SessionsController 

    def create 
    @company=Company.new(company_params)  
    @company.user=helpers.user 

    if @company.save() 
     redirect_to companies_path 
    else 
     render :edit 
    end 
    end 

とRSpecの:

RSpec.describe CompaniesController, type: :controller do 

    let(:user) { instance_double(User) } 

    before do 
     allow_any_instance_of(ApplicationHelper).to receive(:user){user} 
     allow(controller).to receive(:authorize){true} 
    end 

    describe 'Authenticated user with companies' do 

     let(:company_params) { {company:{name:"Albert",domain:"www.albert.com"}} } 
     let(:company) { instance_double(Company) } 

     before do 
     allow(Company).to receive(:new){company} 
     end 

     describe 'POST #create' do 
     context "with valid data" do 

      before { allow(company).to receive(:save){true} } 

      it "redirects to companies_path" do 

      expect(Company).to receive(:new).with(company_params) 
      expect(company).to receive(:user=).with(user) 

      post :create, params:{company: company_params} 
      expect(response).to redirect_to(companies_path) 

      end 

私の意図は非常に簡単です:二重のインスタンスを使用して...作成アクションをテストし、シミュレートするために、使用して模擬するinstance_double(またはスタブ)@company、およびCompany.new「セーブ()」真...など

を返す私はinstance_double、モックのANSスタブを使用してテストする方法を、私は非常によく自分自身を説明する場合は知っているが、controlloerのcreateアクションを与え、ないのですか?

おかげで、すべての

答えて

1

まず、私たちはここに

def create 
    @company=Company.new(company_params)  
    @company.user=helpers.user 

    if @company.save() 
     redirect_to companies_path 
    else 
     render :edit 
    end 
    end 

私たちは、コントローラのcreate動作をテストしているテストする必要があるかを説明しましょう。まずこの行動が何をしているかを見てみましょう。入力としてcomapany_paramsが入力され、データベースに会社レコードが作成されます。

テストも同様です。必要なアクションを渡すだけで、データベースにレコードが作成されているかどうかを確認する必要があります。

RSpec.describe CompaniesController, type: :controller do 

    let(:user) { instance_double(User) } 

    before do 
    # all your authentication stubing goes here 
    allow_any_instance_of(ApplicationHelper).to receive(:user){user} 
    allow(controller).to receive(:authorize){true} 
    end 


    describe 'POST#create' do 
    context 'with valid attributes' do 
     before do 
     post :create, { company:{ name:"Albert", domain:"www.albert.com"} } 
     end 

     it 'responds with success' do 
     expect(response.status).to eq(302) 
     end 

     it 'creates company' do 
     company = Company.find_by(name: "Albert") 

     expect(assigns(:company)).to eq(company) 
     expect(response).to redirect_to(companies_path()) 
     end 
    end 

    context 'with invalid attributes' do 
     before do 
     post :create, { company:{ name:"", domain:""} } 
     end 

     it 'renders new template' do 
     expect(response).to render_template(:edit) 
     end 
    end 
    end 
end 

ここに何もサブする必要はありません。私の知る限りでは、lib classes/background jobs/third party librariesコードをアクション内に使用する場合にのみ、それらのコードをスタブする必要があります。これらのすべてのために、私たちは個別に仕様書を書くでしょう。だからここでもう一度テストする必要はありません。それで私たちはスタブをします。

+0

感謝を許可します私は将来のテストのためにそれを念頭に置いていきます。とにかくPluralsightコースに続いて、私はCreateメソッドのすべてのメソッドをスタブする方法を見てきましたが、Active Recordではなく単純なオブジェクトです。スタブする方法を知りたいです。 '@ company.user ='と 'xxx = Company.new(company_params) '...' allow'と 'expect'を使って...この関連付けをスタブすることは可能ですか?クラッシュなしで作業するための私のコードはどのようにすべきですか?再度、感謝します –

0

Narsimha Reddyのおかげで、テスト方法に関するより良いアイデアが得られます。私は唯一のデcreateの応答試験では

@company=Company.new(company_params)  
@company.user=helpers.user 
if @company.save() 

をスタブにしたい場合は は本家、解決策は、パラメータをうまく利用していた、とあなたのためのallow(company).to receive(:user=) belongs_toの関連付けのための

let(:company_params) {{company:{name:"Albert",domain:"www.albert.com"}}} 
    let(:ac_company_params) {ActionController::Parameters.new(company_params).require(:company).permit!} 

    let(:company) { instance_double(Company) } 

    before do 
    allow(Company).to receive(:new){company} 
    allow(company).to receive(:user=) 
    allow(company).to receive(:save){true} 
    end 

    it "redirects to companies_path" do 
    expect(Company).to receive(:new).with(ac_company_params) 
    expect(company).to receive(:user=).with(user) 

    post :create, params: company_params 
    expect(response).to redirect_to(companies_path) 
    end 
関連する問題