2015-11-19 22 views
0

測試我有一個看起來像這樣的方法:Rspec的如何在注射方法

def self.average_top_level_comments_leaders 
    top_level_comment_count = CrucibleComment.group(:user_id).where(parent_comment_id: nil).order('count_all DESC').count 
    code_review_assigned_count = Reviewer.group(:user_id).order('count_all DESC').count 

    division_result = top_level_comment_count.inject({}) do |result, item| 
     id = item.first #id =12 
     count = item.last #value = 57 
     if (count && code_review_assigned_count[id]) 
     result[id] = (count/ code_review_assigned_count[id]).round(2) 
     #result[12] = 57/12 = 3.3, => {12, 3.3} 
     end 
     result 
    end 
    end 

此方法返回與ID作爲鍵和部門作爲值的結果散列。

我已經成功地測試top_level_comment_count和code_review_assigned計數,但我有麻煩搞清楚我如何測試4周其他的事情,都在做塊:

.first, .last, .round(2), result 

我想測試。第一和這是我到目前爲止:

describe '#average_top_level_comments_leaders' do 
    subject { User.average_top_level_comments_leaders} 

    let(:avg_top_level_comments) { double } 
    let(:code_review_count) { double } 
    let(:item) { double({id: 12}) } 

    context 'when getting the comment count succeeds ' do 
     before do 
     allow(CrucibleComment).to receive(:group).with(:user_id).and_return(avg_top_level_comments) 
     allow(avg_top_level_comments).to receive(:where).with(parent_comment_id: nil).and_return(avg_top_level_comments) 
     allow(avg_top_level_comments).to receive(:order).with('count_all DESC').and_return(avg_top_level_comments) 
     allow(avg_top_level_comments).to receive(:count).and_return(avg_top_level_comments) 

     allow(avg_top_level_comments).to receive(:inject).and_return(avg_top_level_comments) 
     allow(item).to receive(:first).and_return(item) 

     allow(Reviewer).to receive(:group).with(:user_id).and_return(code_review_count) 
     allow(code_review_count).to receive(:order).with('count_all DESC').and_return(code_review_count) 
     allow(code_review_count).to receive(:count).and_return(code_review_count) 
     allow(code_review_count).to receive(:round).with(2).and_return(code_review_count) 
     end 

     it 'and the correct parameters are called' do 
     expect(CrucibleComment).to receive(:group).with(:user_id) 
     subject 
     end 

     it 'and comment count is calling descending correctly' do 
     expect(avg_top_level_comments).to receive(:order).with('count_all DESC') 
     subject 
     end 

     it 'item gets the first result' do 
     expect(item).to receive(:first) 
     subject 
     end 
    end 
    end 

我不能得到最後它的聲明傳遞。我試圖期望(item).to接收(:first),但它在錯誤中表示這是:

失敗/錯誤:期望(item).to接收(:first) (Double).first *(任何參數)) 預計:1次與任何參數 收到:0次與任何參數

任何想法,爲什麼這不是通過?另外兩個公司都通過

+0

恕我直言,你測試是緊密耦合。而不是所有的存根,設置數據,以便該調用返回你應該知道它應該並確保它。你不希望你的測試失敗,只是因爲我把'round'改成了相同的東西(比如'(... + 0.5).floor'或者其他東西)。 –

+0

@PhilipHallstrom現在我想到了,我只是想測試「結果」我怎麼測試它? – Jay266

回答

2

item雙從未在測試中使用,所以當它到達:

expect(item).to receive(:first) 

失敗。

如果你期待item雙待這裏inject塊中使用:

division_result = top_level_comment_count.inject({}) do |result, item| 

僅僅憑藉具有相同名稱它,它不工作的方式。您需要在avg_top_level_comments double上定義一個方法,當inject被調用時返回item double。

但是,你不應該那樣做。拋出所有這些,並使用真實模型實例進行測試。閱讀和維護會更容易。

+0

我該如何做這個測試的真實模型實例?你能給個例子嗎? – Jay266

+0

在測試數據庫中創建行,使用固定設備或工廠,並讓示波器找到它們。它確實需要工作,而且速度會更慢,但對最終結果你會有更多的信心。 – zetetic

+0

在這種情況下,我無法使用數據庫。它必須全都嘲弄。這可能嗎? – Jay266