如何将模拟注入私有方法?

时间:2019-03-11 05:41:07

标签: java junit mocking

当我访问公共方法时,模拟对象运行良好。但是当我访问私有方法时,它不起作用。

我的模拟课程:

@component
public class Test{

public List<String> list(){
 // some function}
}

我的主班:

@component
public class Test2{
private string method(String method){
//here where i have to use mock object
//some function
}
}

我的测试案例:

public class JunitTestCases{

@Mock
Test test;

@Autowired
@InjectMocks
Test2 test2
public void Oncall{
Test2 test=new Test2();
Method method=Test2.class.getDeclaredMethod("method",String.class);
method.setAccessible(true);
method.invoke(test, "data");}
}

我遇到以下错误。

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.TestCases.method(TestClass.java:198)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at com.MainClass.validate(MainClass.java:149)
... 21 more
有什么建议吗?我该如何运作?

2 个答案:

答案 0 :(得分:0)

用于写作测试的演示班

public class PowerMockDemo {

    public Point callPrivateMethod() {
        return privateMethod(new Point(1, 1));
    }

    private Point privateMethod(Point point) {
        return new Point(point.getX() + 1, point.getY() + 1);
    }
}

演示类的测试类

@RunWith(PowerMockRunner.class)
@PrepareForTest(PowerMockDemo.class)
public class PowerMockDemoTest {

    private PowerMockDemo powerMockDemoSpy;

    @Before
    public void setUp() {
        powerMockDemoSpy = PowerMockito.spy(new PowerMockDemo());
    }

    @Test
    public void testMockPrivateMethod() throws Exception {
        Point mockPoint = mock(Point.class);

        PowerMockito.doReturn(mockPoint)
            .when(powerMockDemoSpy, "privateMethod", anyObject());

        Point actualMockPoint = powerMockDemoSpy.callPrivateMethod();

        assertThat(actualMockPoint, is(mockPoint));
    }
}

答案 1 :(得分:0)

在调用方法中,使用 string.class [paramter] 代替 Class [] [parameterArray]。

无需为Test2.class创建其他对象,您使用过的@injectMocks只需在invoke方法中使用变量即可。

public class JunitTestCases{

@Mock
Test test;

@InjectMocks
Test2 test2;

@Test
public void Oncall{

     MockitoAnnotations.initMocks(this);
      Class<?>[] params = new Class<?>[]{String.class};
      Method method=Test2.class.getDeclaredMethod("method",params);
       method.setAccessible(true);
       method.invoke(test2, "data");

    }
}