2012-03-15 3 views
2

У меня вопрос об модульном тестировании.Как провести тестирование частной функции

У меня есть функция, которая делает следующее вещи:

void myFunction(List<MyClass> myList) { 

// 1. Sort the list 
// 2. Post Process the list 

} 

Теперь я хочу, чтобы проверить эту функцию. Но проблема в том, что я не должен проверять эти две вещи одновременно. Поэтому я собираюсь извлечь часть «Опубликовать процесс списка» в качестве отдельной функции.

Но проблема заключается в том, что «Post Process the list» используется только myFunction, и я хочу сделать его закрытым для класса.

Если я сделаю это частным, я не смогу проверить его снаружи.

Каково общее правило такого сценария? Должен ли я изменять частную функцию для публики только для тестирования?

Или, если есть какие-либо другие шаблоны, которые я должен использовать?

Большое спасибо

ответ

3

Метод испытания должен быть пакет локальной только.

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

+1

Один пример mocking framework [Mockito] (http://code.google.com/p/mockito/). Когда вы попадаете в действительно неприятные вещи (например, издевательские статические классы или частные методы), вы также можете использовать [PowerMockito] (http://code.google.com/p/powermock/) – radimpe

0

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

0

Еще одно голосование за пакет-местное. Просто убедитесь, что ваш недавно выставленный метод четко назван и задокументирован так, что в будущем он не будет вызван ненадлежащим образом.

2

Как уже говорилось, вам не нужно публиковать публичный метод, просто пакет видимый.

Google Guava имеет аннотацию @VisibleForTesting, которая предназначена для ситуаций, подобных этому. Вы помещаете эту аннотацию на метод, просто чтобы подтвердить, что причина, по которой метод не является частной, предназначена только для тестирования. Аннотации ничего не делают, это всего лишь предупреждение для программистов, что они не должны вызывать это из-за пределов класса. (Некоторый статический инструмент проверки кода мог в принципе проверить, не вызваны ли методы с этой аннотацией из любого места, кроме внутри класса или из тестового кода).

Ofcourse это отвратительно, чтобы изменить свой код, чтобы сделать это только для тестирования. Если вы хотите этого избежать, вы можете сделать трюки с отражением, чтобы позвонить по частному методу:

public class Sandbox { 
    public static void main(String[] args) throws Exception { 
     Example e = new Example(); 

     Method m = Example.class.getDeclaredMethod("myFunction", List.class); 
     m.setAccessible(true); 
     m.invoke(e, Arrays.asList("one", "two", "three")); 
    } 
} 

class Example { 
    private void myFunction(List<String> data) { 
     System.out.println("Hey, what are you doing! " + data); 
    } 
} 
0

От этого зависит.

Доза подпрограммы содержит общее поведение, которое вы должны извлечь?

Возьмите свою первую подпрограмму в качестве примера.Если вы не сортируете свой список по Comparator<T>, вам следует его реорганизовать, а затем проверить этот класс Comprartor<T> вместо частного метода. Если Post process на самом деле являются некоторым алгоритмом или общей бизнес-логикой, вы можете захотеть реорганизовать его с помощью шаблона стратегии, а затем проверить класс, который вы только что извлекли.

Дело в том, что если частный метод достаточно сложный, чтобы потребовать единичный тест, то вероятность того, что вы, вероятно, не поместите их туда, в противном случае вам нужно просто проверить его публичный API.

Это устаревшая система, и на этот процесс потребуется реорганизовать этот метод.

check Bad Smells in Code : Long method для длинного метода рефакторинга Method Method - хорошая стратегия для подобных вещей.

Все в порядке, я просто хочу их протестировать.

Тогда вы можете test through Java reflection API, и я считаю, что есть некоторые насмешливые рамки, такие как PowerMock также могут помочь вам.

0

Ниже вы можете рассмотреть возможность тестирования частного метода.

1.create public method written only for the purpose of testing. (or) 

2.create nested class for testing (or) 

3.use reflection to test it. 

useful link, another useful link from stackoverflow

0

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

Вопрос о попытке изолировать возвращаемые значения частных методов для имитации различных условий часто является действительным. Я думаю, что это «часть более широкого вопроса о том, как написать тестовый код.

Один подход с очень небольшими накладными расходами заключается в том, чтобы полагаться на базовое переопределение методов. Вы можете сделать свои частные методы защищенные виртуальные вместо этого, и переопределить их в тесте: Вот пример того, что тоже:
http://www.unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html пример является C#, но понятие относится ко всем объектно-ориентированных языков

Смежные вопросы