我需要存根这个方法中的所有东西才能通过吗?
Do I need to stub EVERYTHING in this method in order to pass?
我通常是 mocha 的新手,我讨厌使用它 gem 但我需要使用它才能通过我正在构建的测试。给我带来问题的是我应该嘲笑什么以及我应该如何嘲笑它。为了说明我的观点,下面是我正在测试的方法示例:
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 调用中获取一些统计数据,然后计算它们以确定我的 bounce/complaint 速率是否超出了限制。上限分别为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
。我四处搜索了一下,得出的结论是没有办法存根变量。我也看了这个 link 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
有更简单的方法吗?
即使有一种存根局部变量的方法,该功能也会产生非常难以维护的测试,因为如果不更改测试就无法重构代码。
嵌套的存根也有设计味道 - 您的测试将了解太多的实现细节并且将变得无法维护。
对第三方代码存根也是如此,因为对第三方库的任何更改都将允许您的测试通过,而代码不起作用。
围绕 AWS SimpleEmailService - 网关创建您自己的包装器要好得多。您将实现它以具有非常狭窄的稳定接口,例如
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
然而,显式传递依赖项可以让您拥有更易于维护的代码和更简单的测试。
我通常是 mocha 的新手,我讨厌使用它 gem 但我需要使用它才能通过我正在构建的测试。给我带来问题的是我应该嘲笑什么以及我应该如何嘲笑它。为了说明我的观点,下面是我正在测试的方法示例:
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 调用中获取一些统计数据,然后计算它们以确定我的 bounce/complaint 速率是否超出了限制。上限分别为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
。我四处搜索了一下,得出的结论是没有办法存根变量。我也看了这个 link 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
有更简单的方法吗?
即使有一种存根局部变量的方法,该功能也会产生非常难以维护的测试,因为如果不更改测试就无法重构代码。
嵌套的存根也有设计味道 - 您的测试将了解太多的实现细节并且将变得无法维护。
对第三方代码存根也是如此,因为对第三方库的任何更改都将允许您的测试通过,而代码不起作用。
围绕 AWS SimpleEmailService - 网关创建您自己的包装器要好得多。您将实现它以具有非常狭窄的稳定接口,例如
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
然而,显式传递依赖项可以让您拥有更易于维护的代码和更简单的测试。