使用Mockit做类似JMockit的MockUp

问题描述 投票:0回答:1

我想用Jockock做类似于Mockup的'MockUp'。

我想控制扩展我要测试的类的类方法的功能。但是我有一个问题,就是方法是私有的,所以我认为我不能使用Mockito,需要使用PowerMock。

问题

Class A extends B{...}

Class B {
  private Header generateHeaderForServiceCall(c,d,f,g,h,j){...}
} 

在我的ATest类中{在@Before我想模拟generateHeaderForServiceCall(.....)的情况下,只返回为我创建的默认Header。 }

所以,使用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吗?

-------------------------------------- UPDATE ----- -------------------------

所以,我要测试的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时,它将尝试执行该方法的逻辑并失败,因为标头是基本的。但是我尝试做的是模拟这个,只是不带逻辑地返回默认的Header。

2-如果我像对ClassB的某些方法一样将generateHeaderForServiceCall更改为受保护的,并为此使用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(....)已保护访问包装内

谢谢

mocking mockito powermock mockups
1个回答
0
投票

听起来像您正在寻找spy


所以,我可以使用Mockito吗?我需要使用PowerMock吗?

如果是私有的,则需要使用spy,如果仅受保护的PowerMockito可以处理它。

我可以同时使用Mockito和PowerMockito吗?

[Mockito是基于PowerMockito的,所以是。


请注意,Mockito应该谨慎使用,例如,用于测试遗留代码。通常的建议是重构您的代码。

spy注释需要包含@PrepareForTest,在这种情况下,在此情况下,字节码被修改了class

这里是使用Class A返回而不是String的简化示例:

Header
© www.soinside.com 2019 - 2024. All rights reserved.