Я хочу сделать что-то похожее на 'MockUp' из JMockit, но с Mockito.
Я хочу управлять компиляцией метода класса, который расширяет класс, который я хочу протестировать. Но у меня есть одна проблема, которая заключается в том, что метод является частным, поэтому я думаю, что не могу использовать Mockito, и мне нужно использовать PowerMock.
Проблема
Class A extends B{...}
Class B {
private Header generateHeaderForServiceCall(c,d,f,g,h,j){...}
}
В моем классе ATest {In @Прежде чем я хочу издеваться над generateHeaderForServiceCall (.....), просто верните заголовок по умолчанию, созданный для меня. }
Итак, использование JMockit похоже на:
new MockUp<Controller>() {
@Mock
private Header generateHeaderForServiceCall(...) {
return defaultHeader;
}
};
Я лучше укажу свой контекст:
public class B {
private Header generateHeaderForServiceCall(Input A, Input B, Input c, Input D) throws ServiceException {
......
//do stuff
return header}
}
public class A extends B {
@Override
public Response process(Request request) throws SOAException {
//do stuff
try {
method_i_want_to_test(Input A, Input B);
} catch (Exception t) {
throwCorrectException(t, logger);
}
return response;
}
protected Dossier method_i_want_to_test(Input A, Input B) throws
SOAException {
... //do stuff
**Header** **header** = generateHeaderForServiceCall(Input A, Input
B,Input c, Input D);**
// **doLogic** with header returned and return the result
}
}
Что я пытаюсь сделать:
private A aTest;
@Before
public void setUp() throws Exception {
PowerMockito.mock(aTest);
PowerMockito.doReturn(defaultHeader).when(aTest,"generateHeaderForServiceCall", params);
}
Итак, когда я иду в method_i_want_to_test и вызываю generateHeaderForServiceCall, я просто хочу получить заголовок по умолчанию и игнорировать входные данные и логику метода. Я хочу издеваться над этим методом, но он частный / защищенный.
Итак, могу ли я сделать с Mockito?
Нужно ли мнеиспользовать PowerMock?
Могу ли я использовать Mockito и PowerMockit вместе?
-------------------------------------- ОБНОВЛЕНИЕ ------------------------------
Итак, мой classA, который я хочу проверить, состоит в следующем:
package mypackage;
import package.ClassB;
@Service
public class ClassA extends ClassB implements Xinterface {
@Inject
public ClassA(InputA inputA, InputB inputB,InputC inputC, InputD inputD) {
...
}
@Override
public ClassAResponse process(ClassARequest request) throws SOAException {
ClassAResponse response = initResponse(inputA, request, new ClassAResponse());
ClassAInput input = request.getInput();
ClassAOutput output = new ClassAOutput();
response.setOutput(output);
try {
/* */
method_i_want_to_test(request.getHeader(), numberInput);
} catch (Exception t) {
throwCorrectException(t, logger);
}
return response;
}
protected Dossier method_i_want_to_test(Header srcHeader, Long numberInput) throws SOAException {
Header header = generateHeaderForServiceCall(inputA,srcHeader,inputF,inputJ,inputK);
OtherServiceRequest request = new OtherServiceRequest();
OtherServiceInput input = new OtherServiceInput();
input.setNumber(numberInput);
request.setInput(input);
request.setHeader(header); // So, you can see the i need the result of generateHeaderForServiceCall method
OtherServiceResponse response = OtherService.process(request);
assertSucessfullResponse(response, "OtherService");
return response;
}
}
Мой ClassB, который содержит закрытые и защищенные методы, таков:
package otherPackage;
...
public class ClassB {
private Header generateHeaderForServiceCall(InputA inputA,Header srcHeader,InputF inputF,InputJ inputJ,InputK inputK) throws ServiceException {
String[] nameInfo = QNameUtil.getServiceQNameInfo(inputA);
String serviceVersion = auxMethod(inputJ, inputF);
//... do more stuff
return result;
}
}
И мой класс тестирования, где я тестирую частные методы с PowerMock и пробую с Mockito, если метод защищен. После этого я объясню, что я получил при запуске обоих тестов:
package package;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.powermock.api.mockito.PowerMockito.doReturn;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassA.class)
public class MyTest {
@InjectMocks
private ClassA classA;
@Mock
private InputA inputA;
@Mock
private InputB inputB;
@Mock
private InputC inputC;
@Mock
private InputD inputD;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
classA = new classA( inputA, inputB,inputC, inputD);
}
@Test
public void processPrivateMethod() throws Exception{
defaultHeader = Aux.createDefaultHeader();
//create the spy of my ClassA
classA spy = PowerMockito.spy(classA);
// Define what I want the method 'generateHeaderForServiceCall' returns when called
doReturn(defaultHeader).when(spy, "generateHeaderForServiceCall", inputA,defaultHeader,inputF,inputJ,inputK);
// I try to call the method 'method_i_want_to_test' with classA variable @Injected and with spy of ClassA
//classA.method_i_want_to_test(defaultHeader,inputNumber);
spy.method_i_want_to_test(defaultHeader,inputNumber);
}
}
1 - когда я запускаю этот тест, processPrivateMethod в методе отладки, когда generateHeaderForServiceCall вызывается, он пытается выполнить логику метода и терпит неудачу, потому что заголовок является базовым. Но я пытаюсь сделать это и просто вернуть заголовок по умолчанию без логики.
2 - Если я изменю generateHeaderForServiceCall для защищенного типа некоторых методов ClassB, и для этого использую mockito:
@Test
public void processProtectedMethod() throws Exception{
defaultHeader = JUnitTestUtil.createDefaultHeader();
when(classA.generateHeaderForServiceCall(inputA,defaultHeader,"ccccccc","dxdx",5464564)).thenReturn(defaultHeader);
classA.method_i_want_to_test(defaultHeader,inputNumber);
}
Но он возвращает ошибку, потому что методзащищен (та же ошибка, если он частный, и я использую mockito).
Ошибка: java: generateHeaderForServiceCall (....) имеет защищенный доступ в пакете
Попытки:
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
// Partial mock to mock methods in parent class
child = new ClasseA(...){
@Override
protected Header generateHeaderForServiceCall(...) throws ServiceException {
//mock logic here
return aux.createDefaultHeader();;
}
};
}
@Test
public void processPrivateMethod() throws Exception{
defaultHeader = aux.createDefaultHeader();
//when
Dossier bdoo = child.method_i_want_to_test(...);
}
2-
@Test
public void processPrivateMethod() throws Exception{
defaultHeader = JUnitTestUtil.createDefaultHeader();
child = PowerMockito.spy(new ClasseA(...));
PowerMockito.doReturn(defaultHeader).when(child, "generateHeaderForServiceCall", context,defaultHeader,"ccccccc","dxdx",5464564);
//when
Dossier bdoo = child.method_i_want_to_test(...);
}
3-
@Test
public void processPrivateMethod() throws Exception{
defaultHeader = JUnitTestUtil.createDefaultHeader();
child = PowerMockito.spy(new ClassA(...));
father = PowerMockito.spy(new ClasseB());
PowerMockito.doReturn(defaultHeader).when(father, "generateHeaderForServiceCall", context,defaultHeader,"ccccccc","dxdx",5464564);
//when
Dossier bdoo = child.method_i_want_to_test(...);
}
Никто не делает то, что я хочу. Все идут в метод generateHeaderForServiceCall в классе B и пытаются сделать логику внутри. Спасибо