Rails模型测试 - should_receive方法不起作用

时间:2016-01-31 01:11:52

标签: ruby-on-rails unit-testing ruby-on-rails-4 rspec rspec-rails

我正在编写一种非常简单的方法。每当推荐人推荐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

2 个答案:

答案 0 :(得分:2)

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)}

答案 1 :(得分:2)

User.find不会返回与@referer相同的对象;它将返回表示数据库中同一用户的User的不同实例。

您可以验证是否已将正确的用户ID传递到refund_membership_fees_paid,而不是检查是否调用了RefererRefundAlert.new.async.perform

另外,正如其他人提到的那样,您应该在运行测试方法之前设定您的期望。

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