I've got a class that look 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
In testing the #nasty_bars_present? I'd method like to write an rspec test that stubs the bars association but allows the where to execute naturally. Something like:
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 test above gives an error about there being no method where for an array. How can I wrap the mock so the where will execute appropriately?
Thanks!
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
This way, if you call bars.where(bar_type: "Nasty")
without the specific conditions in the where statement, you won't get the bar double with bar_type: "Nasty"
. It could be reusable for future mocking of bars (at least for returning a single instance, for multiple instances, you would add another double).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With