2013-09-01 100 views
0

我在Rspec寫了一些測試,並試圖通過has_and_belongs_to_many關聯將carrier推送到user。以下是我寫的測試,但是我用箭頭表示的行似乎沒有通過。我意識到我嘲笑了運營商,但不是用戶,我想知道這是否導致HABTM協會的問題。這是問題還是有什麼我失蹤?我是新來的嘲笑和磕頭,但盡我所能!Rspec:我如何測試陣列推送?

describe UsersController do 
    describe 'get #add_carrier' do 
    let(:user) { build(:approved_user) } 

    let(:carrier) { mock_model(Carrier).as_null_object } 
    before{ Carrier.stub(:find).and_return(carrier) } 

    it 'associates the Carrier to the User' do 
     expect(user.carriers).to eq [] 
     user.should_receive(:carriers).and_return([]) 
    --> (user.carriers).should_receive(:push).with(carrier).and_return([carrier]) 
     (user.carriers).push(carrier) 
     (user.carriers).should include carrier 
    end 
    end 
end 

回答

0

存根通常用於想要做適當的單元測試時,除了被測試的方法外存留任何東西。當你測試一個調用命令方法的方法時,通常會使用Mocks(帶有期望的存根)(即有一些影響的方法,例如更改某些數據或保存記錄),並且要確保它被調用。

這個特定的測試,在控制器中給出它,似乎是在錯誤的級別測試事情 - 它測試的是方法內部的東西,而不是方法本身。看看rspec docs

不知道您正在測試的代碼,確切地確定如何測試有點棘手。 #add_carrier聽起來像一個應該簡單地測試一個載體是否被添加的方法,所以大概我們可以測試消息期望。這個測試似乎也在測試getter方法#carriers,這對於一個單元測試來說似乎有點多(但是我完全理解了它的存在)。

另請注意,分享您收到的錯誤肯定會有所幫助。

無論如何,你可以試試下面的:

describe UsersController do 
    describe 'get #add_carrier' do # Should this really be a GET? 
    subject { get :add_carrier } 

    let(:user) { build(:approved_user) } 
    let(:carrier) { mock_model(Carrier).as_null_object } 

    before do 
     controller.stub(:user) { user } 
     Carrier.stub(:find) { carrier } 
    end 

    it "associates the Carrier to the User" do 
     user.carriers.should_receive(:push).with(carrier).and_call_original 
     subject 
     user.carriers.should include carrier 
    end 
    end 
end 

上user.carriers的原始值沒有預期(應在用戶模型中測試)。對推送工作的細節沒有任何期望 - 再一次應該在其他地方進行測試。相反,只是確認重要的命令消息被調用。我不是100%確定我們應該做#and_call_original並確認結果,因爲這些都是我們也可以在模型單元測試中測試的結果(Carrier#推送的結果),但是爲了讓我安心在這裏。

請注意,這是全部從內存中寫入,所以請讓我知道,如果任何它不起作用。