I have a Rails controller action to test. In that action, a method User.can? is invoked several times with different parameters. In one of the test case for it, I want to make sure that User.can?('withdraw') is invoked. But I don't care about invocations of User.can? with other parameters.
def action_to_be_tested
...
@user.can?('withdraw')
...
@user.can?('deposit')
...
end
I tried below in the test:
User.any_instance.expects(:can?).with('withdraw').at_least_once.returns(true)
But the test failed with message indicating unexpected invocation of User.can?('deposit'). If I add another expectation with parameter 'deposit', the test passed. But I am wondering if there are any ways such that I could just focus on the invocation with 'withdraw' parameter (because other invocations are irrelevant to this test case).
You can pass a block to with
and have that block inspect the arguments. Using that, you can construct a list of expected invocations:
invocations = ['withdraw', 'deposit']
User.any_instance.expects(:can?).at_most(2).with do |permission|
permission == invocations.shift
end
Each time can?
is called, Mocha will yield to the block. The block will pull the next value off the list of expected invocations and check it against the actual invocation.
I just found a workaround, by stubbing out invocations with irrelevant parameters:
User.any_instance.expects(:can?).with('withdraw').at_least_once.returns(true)
User.any_instance.stubs(:can?).with(Not(equals('withdraw')))
http://mocha.rubyforge.org/classes/Mocha/ParameterMatchers.html#M000023
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With