15

我有一个 Rails 控制器动作要测试。在那个动作中,一个方法 User.can? 使用不同的参数多次调用。在其中一个测试用例中,我想确保调用 User.can?('withdraw') 。但我不关心 User.can 的调用?与其他参数。

def action_to_be_tested
  ...
  @user.can?('withdraw')
  ...
  @user.can?('deposit')
  ...
end

我在测试中尝试了以下内容:

User.any_instance.expects(:can?).with('withdraw').at_least_once.returns(true)

但测试失败,消息表明意外调用 User.can?('deposit')。如果我使用参数“存款”添加另一个期望,则测试通过。但是我想知道是否有任何方法可以让我只关注带有“withdraw”参数的调用(因为其他调用与这个测试用例无关)。

4

3 回答 3

22

您可以将一个块传递给该块with并让该块检查参数。使用它,您可以构建预期调用的列表:

invocations = ['withdraw', 'deposit']
User.any_instance.expects(:can?).at_most(2).with do |permission|
  permission == invocations.shift
end

每次can?调用时,Mocha 都会屈服于该块。该块将从预期调用列表中提取下一个值,并根据实际调用对其进行检查。

于 2014-03-19T00:03:02.303 回答
19

我刚刚找到了一种解决方法,方法是使用不相关的参数删除调用:

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

于 2012-03-28T04:52:57.877 回答
3

@Innerpeacer 版本的更简单版本是:

User.any_instance.stubs(:can?).with(any_parameters)
User.any_instance.expects(:can?).with('withdraw')
于 2021-01-29T12:54:14.010 回答