Вызов частного метода через JMockit для тестирования результата
Я использую JMockit 1.1, и все, что я хочу сделать, это вызвать частный метод и проверить возвращаемое значение. Однако мне трудно понять, как это сделать из примера JMockit De-Encapsulation.
Метод, который я пытаюсь проверить, является частным методом в этом классе:
public class StringToTransaction {
private List<String> parseTransactionString(final String input) {
// .. processing
return resultList;
}
}
И мой тестовый код ниже.
@Test
public void testParsingForCommas() {
final StringToTransaction tested = new StringToTransaction();
final List<String> expected = new ArrayList<String>();
// Add expected strings list here..
new Expectations() {
{
invoke(tested, "parseTransactionString", "blah blah");
returns(expected);
}
};
}
И ошибка, которую я получаю, это:
java.lang.IllegalStateException: Отсутствует вызов для изделенного типа в эта точка; убедитесь, что такие вызовы появляются только после объявление подходящего макетного поля или параметра
Возможно, я неправильно понял весь API здесь, потому что я не думаю, что хочу издеваться над классом. Просто проверьте результат вызова частного метода.
Ответы
Ответ 1
Я думаю, вы делаете это слишком сложно. Вы не должны использовать блок ожиданий. Все, что вам нужно сделать, это что-то вроде этого:
@Test
public void testParsingForCommas() {
StringToTransaction tested = new StringToTransaction();
List<String> expected = new ArrayList<String>();
// Add expected strings list here..
List<String> actual = Deencapsulation.invoke(tested, "parseTransactionString", "blah blah");
assertEquals(expected, actual);
}
В принципе, вызовите частный метод через Deencapsulation и проверьте, что фактическое значение равно ожидаемому. Так же, как если бы этот метод был общедоступным. Никаких издевательств не делается, поэтому блока ожиданий не требуется.
Ответ 2
В этот момент я не знаю, можно ли использовать JMockit для этого. Тестирование моего частного метода можно выполнить с помощью простого старого отражения, хотя я начал это упражнение, чтобы узнать о JMockit (и проверить свой код). Если JMockit не может быть использован для этого, вот как я могу использовать отражение вместо этого.
@Test
public void testParsingForCommas() throws Exception {
StringToTransaction tested = new StringToTransaction();
ArrayList<String> expected = new ArrayList<>();
expected.add("Test");
Method declaredMethod =
tested.getClass().getDeclaredMethod("parseTransactionString",
String.class);
declaredMethod.setAccessible(true);
Object actual = declaredMethod.invoke(tested, "blah blah");
assertEquals(expected, actual);
}
Вызов setAccessible(true)
здесь важен, или invoke
взорвется при вызове частного метода.
declaredMethod.setAccessible(true);
Но вы хотите знать, что действительно круто? Если вы не вызываете setAccessible(true)
, он взорвется с помощью java.lang.StackOverflowError
!:)
Ответ 3
Почему вы хотите напрямую проверить частный метод? В большинстве случаев API-методы, то есть методы публичного интерфейса, тестируются модулем, поскольку частные методы будут также косвенно протестированы вместе с ними. Вы можете поместить выражения assert с ожидаемыми значениями из частных методов, где вы вызываете их в общедоступных методах. Поэтому, если assert не удается, вы уверены, что существует некоторая проблема с частным методом. Поэтому вам не нужно тестировать его отдельно.
Ответ 4
начать с 1.35 (?) jmockit удалил этот вспомогательный метод. по причинам, что это уже не полезно (что я не совсем понимаю)
но да, эта утилита доступна где-то в другом месте
org.springframework.test.util.ReflectionTestUtils
Ответ 5
Как уже упоминалось @Jeff Olson, вы также можете вызвать частные методы компонента, объявив их @Tested
.
Вот пример:
'''Джава
@Tested
private YourServiceImplClass serviceImpl;
@Test
public void testPrivateMethod() {
List<String> expected = new ArrayList<String>();
// Add expected strings list here..
List<String> actual = Deencapsulation.invoke(serviceImpl, "yourPrivateMethod", "arguments");
assertEquals(expected, actual);
}
"""