我通常是摩卡新手,我讨厌使用这个宝石,但我需要使用它来传递我正在构建的测试。给我带来问题的是我应该嘲笑的东西以及我应该如何嘲笑它。为了说明我的观点,以下是我正在测试的方法示例:
def statistics_of_last_24_hrs
stats = ses.statistics.find_all { |s| s[:sent].between?(Time.now.utc - 24.hours, Time.now.utc) }
sent_last_24_hrs = ses.quotas[:sent_last_24_hours].to_f
no_of_bounces = stats.inject(0.0) { |a, e| a + e[:bounces] }
no_of_complaints = stats.inject(0.0) { |a, e| a + e[:complaints] }
bounce_rate = sent_last_24_hrs.zero? ? 0.0 : (no_of_bounces / sent_last_24_hrs) * 100
complaint_rate = sent_last_24_hrs.zero? ? 0.0 : (no_of_complaints / sent_last_24_hrs) * 100
fail(Reverification::SimpleEmailServiceLimitError, 'Bounce Rate exceeded 5%') if bounce_rate >= 5.0
fail(Reverification::SimpleEmailServiceLimitError, 'Complant Rate exceeded .1%')if complaint_rate >= 0.1
end
基本上,此代码正在执行的操作是从Amazon api调用获取一些统计信息,然后计算它们以确定我的跳出/投诉率是否超出限制。限额分别为5%和0.1%。
基本上,对于我的测试,我真正需要做的是将变量bounce_rate
和complaint_rate
存根,以便测试是否抛出了正确的异常。
这是我陷入困境的地方。这是一个我最好写的准系统测试:
it 'should raise SimpleEmailServieLimitError if bounce rate is above 5%' do
assert_raise Reverification::SimpleEmailServiceLimitError do
Reverification::Process.statistics_of_last_24_hrs
end
end
如何将bounce_rate
和complaint_rate
存根。我已经做了一些搜索并得出结论,没有办法存根变量。我也查看了这个链接List of Mocha Methods这证实了我的发现。
有没有办法可以像这样写一个测试:
it 'should raise SimpleEmailServieLimitError if bounce rate is above 5%' do
stubs(:bounce_rate).returns(true)
assert_raise Reverification::SimpleEmailServiceLimitError do
Reverification::Process.statistics_of_last_24_hrs
end
end
或者我必须在此方法中存根每个方法调用,以便测试看起来像这样:
it 'should raise SimpleEmailServieLimitError if bounce rate is above 5%' do
sent_last_24_hrs = 20
over_bounce_limit = MOCK::AWS::SimpleEmailService.over_bounce_limit
AWS::SimpleEmailService.any_instance.stubs(:statistics).returns(stub(find_all: over_bounce_limit))
AWS::SimpleEmailService.any_instance.stubs(:quotas).returns(stub(sent_last_24_hours: sent_last_24_hrs))
etc. etc. etc...........
assert_raise Reverification::SimpleEmailServiceLimitError do
Reverification::Process.statistics_of_last_24_hrs
end
end
有更简单的方法吗?
答案 0 :(得分:0)
即使存在存根局部变量的方法,该功能也会产生很难维护的测试,因为您无法在不更改测试的情况下重构代码。
嵌套存根也有设计气味 - 你的测试会知道太多的实现细节,并且会变得无法维护。
对于存根第三方代码也是如此,因为对第三方库的任何更改都将允许您的测试在代码不起作用时通过。
围绕AWS SimpleEmailService - gateway创建自己的包装器要好得多。你实现它有一个非常狭窄的稳定界面,如
class BounceStatistics
def no_of_bounces
def no_of_complaints
def sent_last_24_hrs
end
由于此接口是您自己的并且它是稳定的,因此您可以安全地存根并为测试提供替代实现:
assert_raise Reverification::SimpleEmailServiceLimitError do
Reverification::Process.statistics_of_last_24_hrs(
stub(no_of_bounces: 2, no_of_complaints: 3, sent_last_24_hrs: 5))
end
或者您可以将其实现为
BounceStatistics.any_instance.stubs(:no_of_bounces).returns(2)
BounceStatistics.any_instance.stubs(:no_of_complaints).returns(3)
BounceStatistics.any_instance.stubs(:sent_last_24_hrs).returns(5)
assert_raise Reverification::SimpleEmailServiceLimitError do
Reverification::Process.statistics_of_last_24_hrs
end
但是,明确地传递依赖项可以让您拥有更多可维护的代码和更简单的测试。