Как проверить приватные функции в модуле - PullRequest
1 голос
/ 18 апреля 2011

У меня есть вопрос из двух частей:

Часть 1

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

Я прочитал этот пост стека по поводу переполнения стека, который принято делать:

module GTranslate
  class Translator
    def perform( text ); 'hola munda'; end
  end

  def self.translate( text )
    t = Translator.new
    t.perform( text )
  end
end

, а затем написать тесты для открытых методов класса GTranslate::Translator.Однако я не хочу, чтобы этот класс мог создавать экземпляры или вызывать методы для них.

Часть 2

Видя, что открытый метод в модулеопределяется как self.someMethodName, означает ли это, что вспомогательные методы должны быть определены как self.helperName?

Не будет экземпляра модуля (если вы даже можете создавать экземпляры модулей (я новичок вRuby)), поэтому я не могу использовать метод send, определенный в экземпляре, чтобы вызвать метод из моих тестов?

Есть идеи?

Ответы [ 3 ]

5 голосов
/ 18 апреля 2011

Есть некоторые споры о тестировании частных методов, как вы увидите в других ответах. Прежде чем проверять их, вы должны подумать, является ли это лучшим выбором. У Дэвида Брэди есть замечательный подколл с Робертом С. (дядей Бобом) Мартином , где они обсуждают эту проблему и некоторые из возможных решений, включая тестирование через открытый интерфейс и рефакторинг в отдельный класс.

Как говорится, это Руби. Если вы хотите протестировать закрытые методы, используйте instance_eval (или class_eval для методов класса), чтобы запустить тест в контексте модуля.

edit: После некоторых быстрых рабочих модулей IRB потребуется немного больше работы

Дано:

module Foo
  class << self
    private
    def bar
      ...
    end
  end
end

Чтобы проверить Foo.bar, поместите в свой тестовый файл:

Module Foo
  class << self
    puiblic :bar
  end
end

На время ваших тестов bar будет общедоступным и видимым.

конец редактирования

Смотри также:

2 голосов
/ 18 апреля 2011

Я бы сказал, что у вас есть три варианта.

  1. Найдите способ проверить функциональность, используя открытые методы класса. Вся функциональность класса, как правило, должна быть представлена ​​его публичными методами. Если вы не можете протестировать класс, просто используя его открытые методы, это может указывать на более глубокую проблему с дизайном.

  2. Если опция 1 не работает (а иногда и не работает), реорганизуйте приватную функциональность в отдельный класс, в котором эти методы являются публичными. Кажется, это то, что вы предлагаете, и я не вижу проблем с этим. Тестирование является неотъемлемой частью создаваемой вами системы и должно рассматриваться как таковое. На мой взгляд, сделать функционал общедоступным «только для тестирования» вполне допустимо.

  3. Сделайте функции общедоступными и протестируйте их. Это технически проще, но менее чисто, чем вариант 2.

1 голос
/ 18 апреля 2011

Существует два случая:

  1. Закрытый метод вызывается открытым методом или закрытым методом, который вызывается открытым методом, или закрытым методом, который вызываетсязакрытый метод, который вызывается публичным методом или ... (вы поняли).В этом случае вам не нужно тестировать закрытый метод, потому что он уже протестирован через публичный метод.
  2. Закрытый метод никогда не вызывается публичным методом.В этом случае вам также не нужно тестировать его, вы можете просто удалить его, потому что он никогда не вызывается.

Итак, в обоих случаях вам просто не нужно тестировать его впервое место.

(Обратите внимание, что это немного сложнее, так как закрытый метод может быть вызван с помощью отражения или других средств. Но суть в том, что кто-то где-то вызывает закрытый метод, в этом случаеэто проверяется тем, кто-то или никто не вызывает закрытый метод, в этом случае это мертвый код.)

Если я могу сделать небольшую рекламу для разработки через тестирование: в TDD это на самом деле невозможнонепроверенные частные методы существуют.Единственный способ для внедрения частного метода в систему - извлечение из уже протестированного публичного метода.(На самом деле, в TDD для любого непроверенного кода невозможно существование, поэтому утверждение о невозможности существования непроверенных частных методов тривиально верно.)

В общем, частныйметоды обычно создаются путем извлечения их из открытого метода, который стал слишком большим или слишком сложным.Хорошая вещь в этом заключается в том, что Refactoring Extract Method обладает очень удобным свойством: как и все другие Refactorings, он не меняет внешне наблюдаемое поведение, но в отличие от многих других Refactorings, что влечет за собой довольно значительные изменения ввнутренняя логика (например, рефакторинг нулевого объекта или замена условного на полиморфизм рефакторинга), не также изменяет внутреннюю логику.Это просто перемешивает код.(Фактически, с хорошим оптимизирующим компилятором, таким как в Rubinius, IronRuby или JRuby, вызовы приватных методов, вероятно, будут встроены, так что фактически выполняемый код на 100% одинаков как до, так и после извлечения методов..)

Итак, если ваш код был протестирован до того, как вы перешли в закрытый метод, то он гарантированно будет протестирован и после того, как вы переместили его.

...