berkes
berkes

Reputation: 27553

Stubbing :find on a Model Class

Given a model with a method self.fetch_payment_method:

def self.fetch_payment_method
  name = "Omnikassa"
  pm = Spree::PaymentMethod.find(:first, :conditions => [ "lower(name) = ?", name.downcase ]) || raise(ActiveRecord::RecordNotFound)
end

And an rspec test to test this:

it 'should find a payment_method' do
  Spree::PaymentMethod.new(:name => "Omnikassa").save
  @omnikassa.class.fetch_payment_method.should be_a_kind_of(Spree::PaymentMethod)
end

I'd like to improve this, so it does not test the entire stack and database. For that, I'd simply want to stub the ":find" when called on the class Spree::PaymentMethod. However:

it 'should find a payment_method' do
  Spree::PaymentMethod.any_instance.stub(:find).and_return(Spree::PaymentMethod.new)
  @omnikassa.class.fetch_payment_method.should be_a_kind_of(Spree::PaymentMethod)
end

Does not work. I am rather new to the whole BDD/TDD thing and stubbing and mocking is still something magical to me; so I most likely misunderstand what the stubbing and returning is doing exactly.

How should I stub a SomeActiveRecordModel.find?

Upvotes: 0

Views: 188

Answers (1)

alony
alony

Reputation: 10823

You are doing everything correctly, except the stub method should be called on the Spree::PaymentMethod class itself, not on its instances

And it's common practice to return a certain instance with this stub, not just a new one:

it 'should find a payment_method' do
  payment_meth = mock_model(Spree::PaymentMethod)
  Spree::PaymentMethod.stub!(:find).and_return(payment_meth)

  @omnikassa.class.fetch_payment_method.should be_equal(payment_meth)
end

And, by the way, where do you initialize the @omnikassa object?

Upvotes: 4

Related Questions