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