6

Assume this ruby code:

class User
  def self.failed_login!(email)
    user = User.find_by_email(email)
    if user
      user.failed_login_count = user.failed_login_count + 1
      user.save
    end
  end
end

I want to write a test that tests that user.save is never called when an invalid email is given. E.g.:

it "should not increment failed login count" do
   User.expects(:save).never()
   User.failed_login!("doesnotexist")
end

This test currently passes, but it also passes when I provide a valid email address.

How do I set up the expectation using Mocha? (or any other mocking framework) such that it tests the save method of any User instance is never called?

(preferably without stubbing/mocking the find_by_email method, as the implementation of how to get the user might change in the future)

Cheers

Vega
  • 27,856
  • 27
  • 95
  • 103
Jim Soho
  • 2,018
  • 2
  • 21
  • 25

2 Answers2

22

For others that might have stumbled unto this, I found the answer in another post that was dealing with RR as the mocking framework... in Mocha you can do this:

User.any_instance.expects(:save).never()
Jim Soho
  • 2,018
  • 2
  • 21
  • 25
  • 1
    Just beware running this with RSpec mocks, since it'll affect _all_ following instances. Mocha pulls the mock down as expected, per spec. – avocade Mar 13 '11 at 16:52
4

alternatively you could do something like

user = mock
User.expects(:find).returns user
user.expects(:save).never
grosser
  • 14,707
  • 7
  • 57
  • 61
  • 5
    The User.expects(:find) would probably be better as User.stubs(:find) in this case, because we don't really care whether User.find is called - just that User#save is not called. – James Mead Dec 02 '10 at 11:02