0

I have a rails controller which I would like to test a method test_method.

class ActiveController < ActionController::Base
  def test_method
    user = acc_users.all_users.find params[:id]
    if !user.active?
      user.call_method!
    end
  end
end

I have to test that call_method isn't being called. This is what I have come up with but I don't think this will work.

 it "should not call call_method" do
    u = user(@acc)
    put :test_method, :id => u.id
    expect(u).not_to have_received(:call_method!)
  end

I followed this question here and found it almost similar except that the method being called is in another class. When I try this above code I get an error message like "expected Object to respond to has_received?"

I believe I will not be able to test this with the given setup as the user is not being injected in the test_method.

call_method is a call to a method that enqueues a job so I want to be sure it doesn't get invoked.

How would I go about testing this method?

thebenman
  • 1,621
  • 14
  • 35

1 Answers1

0

You could use the expect_any_instance_of method on User model with a count, say "n", to test that the model receives a particular method "n" times.

Also, you would have to set this expectation BEFORE actually calling your action because the expectation is based on something that happens inside the action itself, and not on something that the action returns.

The following line should work, assuming your user variable is an instance of the class User:

u = user(@acc)
expect_any_instance_of(User).to receive(:call_method!).once
put :test_method, :id => u.id

Alternately, you could change the spec to behave like a black box, rather than test invocations of particular methods. For example, you could mock call_method! to always return a value such as and then continue your test based on that if that is possible. That could be achieved using expect_any_instance_of(User).to receive(:call_method!).and_return(<some_object>). Your test could later be assumed to behave according to the value of that you have set. This alternate solution is just a suggestion, and it is likely that it may not work according to your specific needs.

Anuj Khandelwal
  • 1,214
  • 1
  • 8
  • 16
  • but I'm running unit tests in parallel and there are some cases where `User` class should receive this method. I don't think this will work reliably in those cases – thebenman Nov 01 '19 at 08:31