2016-03-17 2 views
1

Я вообще новичок в мокко, и я ненавижу использовать этот камень, но мне нужно использовать его, чтобы пройти тест, который я создаю. То, что дает мне проблемы, - это то, что я должен высмеивать и как я должен издеваться над этим. Для того, чтобы проиллюстрировать мою точку зрения, Вот пример метода, который я тестирую:Нужно ли мне заглушить ВСЕ в этом методе, чтобы пройти?

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 

В основном то, что этот код делает получает некоторые статистические данные из АНИ вызова Амазонки, а затем их вычисления, чтобы определить, является ли мой подпрыгивать/жалобы ставка превысила лимит. Предел составляет 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

Даже если бы был способ заглушить локальные переменные, эта функция создаст тесты, которые очень сложно поддерживать, потому что вы не сможете реорганизовать свой код без изменения тестов.

Вложенные заглушки - это также запах дизайна - ваши тесты будут знать о слишком больших деталях реализации и станут неподъемными.

То же самое можно сказать и о том, что для прошивки стороннего кода любые изменения в сторонней библиотеке позволят проходить тесты, пока код не работает.

Гораздо лучше создать свою собственную оболочку вокруг 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 

Однако проходящими зависимостей явно позволяет иметь более ремонтопригодны код и простые тесты.

+0

Спасибо ветровик. Я даже не думал об этом. Очень признателен. –