How to silence an active record relation to check where clause with rspec?

I have a class that looks like this:

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 

When testing #nasty_bars_present? I would like to write an rspec test that drowns out the bar association but allows for natural execution. Sort of:

 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 

The above test gives an error saying that there is no method where for the array. How can I wrap the layout so where will it execute appropriately?

Thanks!

+6
source share
1 answer

For RSpec 2.14.1 (it should also work for RSpec 3.1), I would try this:

 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 

Thus, if you call bars.where(bar_type: "Nasty") without specific conditions in the where statement, you will not get a double line with bar_type: "Nasty" . It can be reused for future mockery of the bars (at least to return one instance, for multiple instances, you would add another double).

+3
source

Source: https://habr.com/ru/post/977778/


All Articles