btakita / rr

RR (Double Ruby) is a test double framework that features a rich selection of double techniques and a terse syntax.
http://github.com/rr/rr
MIT License
501 stars 58 forks source link

Problems with mocking an ActiveRecord model method #75

Open mikeys opened 12 years ago

mikeys commented 12 years ago

Consider the following class and methods: (This class is obviously much more complete, but for the sake of this thread...):

class Order < ActiveRecord::Base

  def check
    if (self.user.phone == "55555555") do
      self.a_certain_method
      return
    end
  end

  def a_certain_method
    # Real implementation goes here
  end

end

And the following Unit Test:

describe :do_route do
it "should call a_certain_method if user phone number matches 55555555" do
  # Create a user
  user = Factory(:user)

  # Set hard-coded phone number
  user.phone = "55555555"
  user.save!

  # Create an order made by the ordering user
  order = Factory(:order, :ordering_user => user)

  # Set expectation for a "a_certain_method" call
  mock(order).a_certain_method

  # Call the tested method
  order.check
end
end

From some reason, the above test produces an RR::Errors::TimesCalledError error, which claims that a_certain_method was called 0 times instead of 1... I've been searching around the web for a solution with no luck.

I've tried building a similiar test on a non-activerecord class, and the test produces no errors. I've used the debugger to check that it does reach the self.a_certain_method line, and also tried using the following instead of mock(order).a_certain_method:

  any_instance_of(Order) do |o|
    mock(o).a_certain_method
  end

Does anyone have any idea how to solve this issue since i'm kind of desperate...

cvshepherd commented 12 years ago

I just encountered the same problem. I can't help but think that I'm doing something wrong, because it seems like a no-brainer. EDIT: Ok, I was just doing it wrong. Forgot to add the parameters to the mock expectation.

mcmire commented 11 years ago

Hey there. I don't quite know why RR was giving you an error, but I did spot this in your code above:

def check
    if (self.user.phone == "55555555") do

This is incorrect Ruby, it should read:

def check
    if self.user.phone == "55555555"

Otherwise, everything you're doing seems correct.

I know this is kind of late and I don't know if you even remember what you were doing here but have you encountered this problem since? Thanks.