2014-11-05 153 views
6

我有一個類,它是這樣的:如何使用rspec測試活動記錄關係來測試where子句?

class Foo < ActiveRecrod::Base 
    has_many :bars 

    def nasty_bars_present? 
    bars.where(bar_type: "Nasty").any? 
    end 

    validate :validate_nasty_bars 
    def validate_nasty_bars 
    if nasty_bars_present? 
     errors.add(:base, :nasty_bars_present) 
    end 
    end 
end 

在測試#nasty_bars_present?我想方法喜歡寫一個rspec測試存根棒協會,但允許自然執行的地方。例如:

describe "#nasty_bars_present?" do 
    context "with nasty bars" do 
    before { foo.stub(:bars).and_return([mock(Bar, bar_type: "Nasty")]) } 
    it "should return true" do 
     expect(foo.nasty_bars_present?).to be_true 
    end 
    end 
end 

上面的測試給出了一個有關數組沒有方法的錯誤。我怎樣才能包裝模擬器,以便在哪裏執行適當的操作?

謝謝!

+0

您使用的是什麼版本的RSpec? – nikkon226 2014-11-05 17:33:07

+0

這個項目在2.14.1上,但我也會對最近發佈的版本感興趣。 – biagidp 2014-11-05 17:41:07

回答

3

對於RSpec的2.14.1(也應該爲3.1 RSpec的工作),我會嘗試這樣的:

describe "#nasty_bars_present?" do 
    context "with nasty bars" do 
    before :each do 
     foo = Foo.new 
     bar = double("Bar") 
     allow(bar).to receive(:where).with({bar_type: "Nasty"}).and_return([double("Bar", bar_type: "Nasty")]) 
     allow(foo).to receive(:bars).and_return(bar) 
    end 
    it "should return true" do 
     expect(foo.nasty_bars_present?).to be_true 
    end 
    end 
end 

這樣一來,如果你打電話bars.where(bar_type: "Nasty")沒有在WHERE語句的具體情況,你贏了」 t得到酒吧雙bar_type: "Nasty"。它可以重複使用,用於將來模擬酒吧(至少對於返回單個實例,對於多個實例,您可以添加另一個實例)。

+0

不應該'double('Bar')''class_double('Bar')'? – 2017-03-07 06:26:38