Как имитировать частный метод для разных результатов в потоке кода

#java #mocking #powermock #private-methods

#java #издевательство #powermock #частные методы

Вопрос:

В моем Java-коде есть частный метод, который необходимо вызвать дважды. Я пишу junits с использованием Powermock. При издевательстве над указанным методом мне нужны два разных результата для двух разных вызовов.

//Я пытался:

 PowerMockito.doReturn("MyString1").doReturn("MyString2").when(spy,"getresult",Mockito.anyString());
  

//Но when() не принимает ничего, кроме объекта spy.

 PowerMockito.doReturn("MyString1").doReturn("MyString2").when(spy).getresult(Mockito.anyString());
  

//when() не позволяет использовать метод getresult, поскольку этот метод getresult объявлен закрытым.

код

 Class A{
String firstString="abc";
String secondString="def";
String result1=getresult(firstString);
String result2=getresult(secondString);

private String getresult(String arg1){
//My code here;
return "AnyString";
}
}
  

JUNIT

 //Declarations
@InjectMocks
A a;
.......
@Test
public void ATest(){
....
/*Suppose I want "MyString1" and "MyString2" as result for calling the method "getresult" for result1 and result2 in Class A*/
A spy=PowerMockito.spy(a);
PowerMockito.doReturn("MyString1").when(spy,"getresult",Mockito.anyString());
....
}
// Please overlook the typos
  

Я получаю ошибку компиляции при использовании кода, который я пробовал.
Как написано в комментариях к коду, я ожидаю два результата «MyString1» и «MyString2» в двух последовательных вызовах метода, как показано в коде.

Заранее спасибо. Приветствуется любой другой подход для достижения результатов.

Комментарии:

1. вы не должны имитировать частные методы

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

3. На практике для частного метода требуется несколько параметров, которые невозможно предоставить в junits. Вот почему мне нужно издеваться над методом. Спасибо.

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

5. @SwastikBanerjee ваши частные методы вызываются в ваших общедоступных методах, именно они передают им информацию. «параметры, которые невозможно предоставить в junits» … для частных методов это бессмыслица

Ответ №1:

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

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

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

Комментарии:

1. «Необходимость в PowerMock в новом коде указывает на серьезные проблемы в дизайне». Нет, это бессмыслица. Если вы не используете фреймворк-макет для тестирования своего кода, у вас либо нет вызовов служб, либо у вас нет модульных тестов. Помните, что ваши модульные тесты должны тестировать модуль, а не все, что за ним стоит. Для этого у вас есть тесты end-2-end.

2. Я говорю конкретно о PowerMock, а не о издевательстве в целом.

3. независимо от того, говорите ли вы о Mockito или PowerMock, вы можете захотеть прочитать комментарии на их официальных страницах, прежде чем объявлять, для чего они предназначены (PowerMock предназначен не только для устаревших приложений. (во всяком случае, не в соответствии с их страницей)

4. Аргумент @Stultuske Januson заключается в том, что для нового и правильно написанного кода должно быть достаточно чего-то вроде Mockito. Необходимость использования более мощного инструмента (например, имитирует статические методы) указывает на то, что код испорчен, потому что вам не нужно использовать что-то более мощное. Видят ли создатели PowerMock это таким образом, на самом деле не имеет значения.

Ответ №2:

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

Однако по следующей ссылке показано, как тестировать частные методы.

https://dzone.com/articles/mock-private-method