2017-10-11 61 views
0

我是測試和學習Rspec的新手,我無法讓它工作。使用instance_double與belongs_to關聯的Rspec3控制器進行測試

(我已閱讀與Rspec3書有效的測試,很多教程...也pluralsight.com)

的情況是非常簡單的。在Companies控制器我想測試去創建方法,該company模型belongs_to user,這是代碼:

我認爲這個問題是測試執行

時: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,使用實例雙...測試創建行動,並模擬「保存()「返回true ...等

我不知道我是否很好地解釋了自己,但是鑑於控制者的create行爲,如何使用mocks ans stubs,instance_double進行測試?

感謝

回答

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方法中存儲所有方法,但不是Activerecord,只是簡單的對象,而且我想知道如何存根,@ company.user =和xxx = Company.new(company_params)'...用'allow'和'expect' ...是否有可能將這些關聯存根?我的代碼應該如何在沒有崩潰的情況下工作?再次感謝 –

0

感謝Narsimha Reddy,我對如何測試有更好的想法。 Eventhough,如果我想存根

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

僅用於測試德create的迴應,該解決方案是一個很好用的參數,並允許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 
相關問題