首页 > 解决方案 > 带有变量的 RSpec 存根对象方法

问题描述

测试一个助手,我遇到了一个问题。

我有一个模型范围: Task.due_within(days)

这在帮助程序中被引用:

module UsersHelper
  ...
  def show_alert(tasks, properties, user)
    pulse_alert(tasks, properties) ||
      tasks.due_within(7).count.positive? ||
      tasks.needs_more_info.count.positive? ||
      tasks.due_within(14).count.positive? ||
      tasks.created_since(user.last_sign_in_at).count.positive?
  end
  ...
end

所以我正在测试 , 和tasksproperties存根user

RSpec.describe UsersHelper, type: :helper do
  describe '#show_alert' do
    it 'returns true if there are tasks due within 7 days' do
      tasks = double(:task, due_within: [1, 2, 3, 4], past_due: [])
      properties = double(:property, over_budget: [], nearing_budget: [])
      user = double(:user)

      expect(helper.show_alert(tasks, properties, user)).to eq true
    end

    it 'returns true if there are tasks due within 14 days' do
      # uh oh. This test would be exactly the same as above.
    end
  end
end

这通过了,但是当我为 编写测试时it 'returns true if there are tasks due within 14 days,我意识到我double(:task, due_within: [])没有与提供给该方法的变量交互。

如何编写一个关心提供给方法的变量的存根?

显然这不起作用:

tasks = double(:task, due_within(7): [1, 2], due_within(14): [1, 2, 3, 4])

标签: ruby-on-railsrspec-rails

解决方案


为了处理不同的情况,你可以尝试这样的事情吗?

allow(:tasks).to receive(:due_within).with(7).and_return(*insert expectation*)
allow(:tasks).to receive(:due_within).with(14).and_return(*insert expectation*)

由于您正在测试 show_alert 方法,因此您可能希望将您的测试单独隔离到 show_alert 方法,即如上所述模拟due_within 的返回值。Due_within 的功能将在单独的测试用例中处理。


推荐阅读