junit и Java: тестирование непубличных методов [дубликат]

Используя эту функцию PHP mysql_escape_string(), вы можете быстро получить хорошую профилактику.

Например:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."'

mysql_escape_string - Сбрасывает строку для использования в mysql_query

Для большей профилактики вы можете добавить в конце ...

wHERE 1=1   or  LIMIT 1

Наконец вы получаете:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."' LIMIT 1
100
задан Ciro Santilli 新疆改造中心法轮功六四事件 11 February 2015 в 13:55
поделиться

13 ответов

Одна философская школа о поблочном тестировании говорит, что необходимо только быть в состоянии протестировать открытые методы, потому что необходимо только быть поблочным тестированием общедоступный API, и что путем выполнения так, необходимо покрывать код в непубличных методах. Ваш пробег может варьироваться; я нахожу, что это иногда имеет место и иногда нет.

После этих слов существует несколько способов протестировать непубличные методы:

  • можно протестировать защищенный и методы объема пакета путем помещения модульных тестов в тот же пакет как классы, которые они тестируют. Это - довольно обычная практика.
  • можно протестировать защищенные методы от модульных тестов в другом пакете путем создания подкласса класса под тестом, который переопределяет методы, которые Вы хотите протестировать, как общественность, и имеющий те переопределенные методы называет исходные методы с супер ключевым словом. Как правило, этот "подкласс тестирования" был бы внутренним классом в классе JUnit TestCase, делающем тестирование. Это - немного больше hacky, по-моему, но я сделал его.

Hope это помогает.

91
ответ дан MattK 24 November 2019 в 04:51
поделиться

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

Думают о самом Вашем классе как о "Единице", не методе. Вы тестируете класс и что он может поддержать допустимое состояние независимо от того, как это - открытые методы, названы.

закрытые методы Вызова могут уничтожить инкапсуляцию и на самом деле делать недействительным тесты.

0
ответ дан Bill K 24 November 2019 в 04:51
поделиться

Ищите "PrivateAccessor.invoke". Мой код импортирует его из "junitx.util", но я не знаю, куда это прибыло из.

0
ответ дан Paul Tomblin 24 November 2019 в 04:51
поделиться

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

предположим у Вас есть вид функциональности, которую Вы хотите выделить в некотором роде внутренний к классу. Например, предположите, что у меня есть что-то вроде этого:

public class HolderOfSomeStrings{

    private List<String> internal_values;

    public List<String> get()
    {
       List<String> out = new ArrayList<String>();
       for (String s:internal_values)
       { 
           out.add(process(s));
       }
      return get;
    }

   private static String process(String input)
   {
     //do something complicated here that other classes shouldn't be interested in
    }

}

точка здесь - то, что junit вынуждает меня обнародовать процесс, или по крайней мере защищенный, или поместить его в свой собственный служебный класс. Но если это - своего рода внутренняя логика HolderOfSomeStrings, мне нисколько не ясно, что это - correct— мне кажется, что это должно быть частным, и создание его более видимая резина код в некотором роде.

2
ответ дан Cody Gray 24 November 2019 в 04:51
поделиться

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

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

3
ответ дан Spoike 24 November 2019 в 04:51
поделиться

Я почти всегда использую Spring в своих проектах Java и, как таковой, мои объекты создаются для внедрения зависимости. Они имеют тенденцию быть довольно детализированными реализациями открытых интерфейсов, которые собраны в контексте приложения. По сути, у меня редко (если когда-нибудь) есть потребность протестировать закрытые методы, потому что сам класс является достаточно маленьким, что это просто не проблема.

, Даже когда я не использую Spring, я склонен принимать те же методы сборки небольших и простых объектов в большие и большие абстракции, каждая из которых относительно проста, но сделала комплекс агрегированными объектами.

, По моему опыту, имея потребность к закрытым методам модульного теста индикатор, который, что Вы тестируете, мог (и если) быть упрощенным.

, Что, будучи, если Вы все еще действительно чувствуете потребность:

  • Защищенные методы могут быть протестированы подклассами;
  • закрытые методы Пакета могут быть протестированы путем помещения модульных тестов в том же пакете; и
  • Закрытые методы могут быть единицей, протестированной путем обеспечения, например, пакету частного метода прокси фабрики. Не идеальный, но частный действительно означает частный.
3
ответ дан cletus 24 November 2019 в 04:51
поделиться

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

public void testPrivateField() throws InterruptedException {
    Class<ClassWPrivateField> clazz = ClassWPrivateField.class;
    try {
        Field privateField = clazz.getDeclaredField("nameOfPrivateField");
        privateField.setAccessible(true); // This is the line
        // do stuff
    } catch(NoSuchFieldException nsfe) {
        nsfe.printStackTrace();
        fail();
    } catch(IllegalAccessException iae) {
        iae.printStackTrace();
        fail();
    }

}
8
ответ дан Cheese Daneish 24 November 2019 в 04:51
поделиться

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

9
ответ дан marcumka 24 November 2019 в 04:51
поделиться

Простое решение должно поместить тесты JUnit в тот же пакет (но различный каталог) и значение по умолчанию использования (т.е. частный на пакет) видимость для методов.

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

9
ответ дан starblue 24 November 2019 в 04:51
поделиться

Когда Вы пишете тест JUnit, необходимо сделать тонкий сдвиг ума: "Я - клиент своего собственного класса теперь". Это означает частный, является частным, и Вы только тестируете поведение, которое видит клиент.

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

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

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

26
ответ дан duffymo 24 November 2019 в 04:51
поделиться

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

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

40
ответ дан Kent Beck 24 November 2019 в 04:51
поделиться

Для заимствования мысли от Andy Hunt даже закрытые методы должны иметь некоторый побочный эффект, которым Вы интересуетесь. Другими словами, их нужно назвать от некоторого открытого метода и выполнить интересную задачу, которая вызывает состояние Вашего объекта измениться. Тест для того изменения состояния.

предположим у Вас есть открытый метод pubMethod и закрытый метод privMethod. При вызове pubMethod он в свою очередь называет privMethod для выполнения задачи (возможно, анализирующий Строку). pubMethod тогда использует эту проанализированную Строку для значений переменных элемента множества в некотором роде или влиять на его собственное возвращаемое значение. Тест путем наблюдения за желаемым эффектом на возвращаемое значение pubMethod или на членские переменные (возможно при помощи средств доступа для получения до них).

2
ответ дан Wil Doane 24 November 2019 в 04:51
поделиться

Вы можете использовать TestNG вместо JUnit, который не заботится о том, является ли метод закрытым или открытым.

1
ответ дан 24 November 2019 в 04:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: