Rails 模型测试 - should_receive 方法无效

Rails model test - should_receive method not working

我正在编写一个非常简单的方法。每当推荐人推荐 5 人成为新用户时,我希望他们获得退款。这意味着当创建新用户时,有一种方法 check_referer 检查推荐他们的人(如果这个人存在)是否应该获得退款,因为他们现在总共推荐了 5 个人。

在测试日志中,根据 puts 语句,我可以看出代码正在运行并且 refund_membership_fees_paid 方法确实被调用了一次。但是测试一直失败:

Failure/Error: @referer.should_receive(:refund_membership_fees_paid).exactly(1).times
   (#<User:0x007fbf46bf1c58>).refund_membership_fees_paid(any args)
       expected: 1 time with any arguments
       received: 0 times with any arguments

测试代码:

describe User, "Test refund_membership_fees_paid method is called" do
  before do
    @referer = User.new()
    @referer.save(validate:false)
    RefererRefundAlert.stub_chain(:new, :async, :perform)
  end
  it "at 5 users" do
    5.times do |index|
        u = User.new(referred_by: @referer.id)
        u.save(validate:false)
    end
    @referer.should_receive(:refund_membership_fees_paid).exactly(1).times
  end
end

型号代码:

def check_referer
  if self.referred_by.present? && User.where(referred_by: self.referred_by).count == 5
    User.find(self.referred_by).refund_membership_fees_paid
  end
end

def refund_membership_fees_paid
  puts "refund_membership_fees_paid method"
  RefererRefundAlert.new.async.perform(self.id)
end

should_receive的作用是设置对后面动作的期望。

例如,如果您的 account.close 操作应该记录关闭,测试将是...

  logger.should_receive(:account_closed)
  account.close

所以你的例子应该重组以把测试放在第一位...

@referer.should_receive(:refund_membership_fees_paid).exactly(1).times
5.times {User.new(referred_by: @referer.id).save(validate: false)}

User.find@referer 不是 return 同一个对象;它将 return 代表数据库中同一用户的 User 的不同实例。

您可以验证是否将正确的用户 ID 传递到 RefererRefundAlert.new.async.perform

,而不是检查是否调用了 refund_membership_fees_paid

此外,正如其他人提到的,您应该在 运行 测试方法之前设置您的期望值。

RefererRefundAlert.new.async.should_receive(:perform)
      .with(@referer.id).exactly(1).times
5.times do |index|
  u = User.new(referred_by: @referer.id)
  u.save(validate:false)
end