#spring-boot #junit #mockito #powermock #powermockito
#весенняя загрузка #junit #mockito #powermock #powermockito
Вопрос:
Я пытаюсь имитировать частный метод внутри моего тестируемого класса, как показано ниже.
public String processPayment(...) {
//some lines
privateMethod(...);
return "";
}
private Object privateMethod(...) {
//some lines
return someObject;
}
Теперь мне нужно протестировать processPayment
метод и макет privateMethod
.
Я попытался создать шпион вышеуказанного класса, но метод вызывается, когда я делаю ниже
final DeviceCheckoutServiceImpl spyDeviceCheckoutService = spy(injectedMockBeanOfAboveClass); //@InjectMock in test class
PowerMockito.doReturn(null).when(spyDeviceCheckoutService, "privateMethod", ArgumentMatchers.anyMap()); //method gets called here
spyDeviceCheckoutService.processPayment(...); //private method isn't mocked somehow, and gets called here too
privateMethod
Вызывается на самой 2-й строке.
Кроме того, the privateMethod
не издевается.
Может быть, я создаю объект-шпион неправильно? Не могу сделать spy(new DeviceCheckoutServiceImpl());
, поскольку для этого требуется создание экземпляра компонента.
Версия Powermockito:
compile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0'
compile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0'
Дайте мне знать, что я здесь делаю не так.
Ответ №1:
В тестовом классе мы вызовем метод spy() org.powermock.api.mockito.PowerMockito
, передав ссылку на класс, который необходимо протестировать:
MockPrivateMethodExample spy = PowerMockito.spy(mockPrivateMethodExample);
Затем мы определяем, что мы хотим делать при вызове этого конкретного частного метода.
PowerMockito.doReturn("Test").when(spy, {$methodName});
MockPrivateMethodExample.java
public class MockPrivateMethodExample {
public String getDetails() {
return "Mock private method example: " iAmPrivate();
}
private String iAmPrivate() {
return new Date().toString();
}
}
MockPrivateMethodTest.java
@RunWith(PowerMockRunner.class)
@PrepareForTest(MockPrivateMethodExample.class)
public class MockPrivateMethodTest {
private MockPrivateMethodExample mockPrivateMethodExample;
// This is the name of the private method which we want to mock
private static final String METHOD = "iAmPrivate";
@Test
public void testPrivateMethod() throws Exception {
mockPrivateMethodExample = new MockPrivateMethodExample();
MockPrivateMethodExample spy = PowerMockito.spy(mockPrivateMethodExample);
PowerMockito.doReturn("Test").when(spy, METHOD);
String value = spy.getDetails();
Assert.assertEquals(value, "Mock private method example: Test");
PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke(METHOD);
}
}
Более подробная информация здесь: https://examples.javacodegeeks.com/core-java/mockito/mockito-mock-private-method-example-with-powermock/
Комментарии:
1. уже пробовал. Метод вызывается всякий раз, когда я это делаю
PowerMockito.doReturn("Test").when(spy, METHOD);
, плюс, метод не издевается. :-/2. @PraveenKamath Не могли бы вы отметить ответ как полезный. Спасибо.
Ответ №2:
Проблема решена! Забыл добавить @PrepareForTest(DeviceCheckoutServiceImpl.class)
тестовый класс.
Ответ №3:
Mockito введен AdditionalAnswers.delegatesTo
для поддержки слежки за весенними прокси и другими подобными вещами:
Проверьте эту проблему: https://github.com/mockito/mockito/issues/529#issuecomment-239494581
Поэтому вместо
spy(proxy)
использованияmock(TestSubject.class,
.
delegatesTo(springProxy))Однако, если аннотации необходимо прочитать, вам понадобится бета-версия mockito 2. Потому что mockito 1.x использует CGLIB, который не копирует аннотации в подкласс mockito. В Mockito 2 используется отличный bytebuddy.
Комментарии:
1. Обнаружена проблема. Не добавлял
@PrepareForTest(DeviceCheckoutServiceImpl.class)
тестовый класс.