Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocha: Can I put a "never" expectation on a stubbed method WITH parameters?

My question is similar to this one: Mocha: stubbing method with specific parameter but not for other parameters

obj.expects(:do_something).with(:apples).never
perform_action_on_obj

The perform_action_on_obj will not call do_something(:apples) as I expect. However, it may call do_something(:bananas). If it does, I get an unexpected invocation failure.

My understanding is that since I placed never at the end of the expectation, it only applied to that specific modified expectation. However it appears that once I start mocking behavior on obj I've "screwed it up" in a sense.

How can I allow other invocations of the do_something method on obj?

EDIT: Here is a clear cut example that demonstrates my issue perfectly:

describe 'mocha' do
  it 'drives me nuts' do
    a = mock()
    a.expects(:method_call).with(:apples)

    a.lol(:apples)
    a.lol(:bananas) # throws an unexpected invocation
  end 
end
like image 556
Brian Avatar asked Dec 16 '22 09:12

Brian


1 Answers

Here's a workaround using ParameterMatchers:

require 'test/unit'
require 'mocha/setup'

class MyTest < Test::Unit::TestCase
  def test_something
    my_mock = mock()
    my_mock.expects(:blah).with(:apple).never
    my_mock.expects(:blah).with(Not equals :apple).at_least(0)
    my_mock.blah(:pear)
    my_mock.blah(:apple)
  end
end

Result:

>> ruby mocha_test.rb 
Run options: 

# Running tests:

F

Finished tests in 0.000799s, 1251.6240 tests/s, 0.0000 assertions/s.

  1) Failure:
test_something(MyTest) [mocha_test.rb:10]:
unexpected invocation: #<Mock:0xca0e68>.blah(:apple)
unsatisfied expectations:
- expected never, invoked once: #<Mock:0xca0e68>.blah(:apple)
satisfied expectations:
- allowed any number of times, invoked once: #<Mock:0xca0e68>.blah(Not(:apple))


1 tests, 0 assertions, 1 failures, 0 errors, 0 skips

In general, I agree with you: this behavior is frustrating to work with and violates the principle of least surprise. It's also hard to extend the trick above to more general cases, since you'll have to write an increasingly complicated 'catchall' expression. If you want something more intuitive, I find RSpec's mocks to be quite nice.

like image 193
charleyc Avatar answered Jan 05 '23 00:01

charleyc