如何使用JUnit测试具有内部私有方法、字段或嵌套类的类?
仅仅为了能够运行测试而更改方法的访问修饰符似乎是不好的。
如何使用JUnit测试具有内部私有方法、字段或嵌套类的类?
仅仅为了能够运行测试而更改方法的访问修饰符似乎是不好的。
当前回答
在C++中:在包含包含要测试的私有函数的类头之前。
使用此代码:
#define private public
#define protected public
其他回答
请参见下面的示例;
应添加以下导入语句:
import org.powermock.reflect.Whitebox;
现在,您可以直接传递具有私有方法、要调用的方法名和其他参数的对象,如下所示。
Whitebox.invokeMethod(obj, "privateMethod", "param1");
您可以使用PowerMockito为要测试的私有方法中调用/使用的私有字段和私有方法设置返回值:
例如,为私有方法设置返回值:
MyClient classUnderTest = PowerMockito.spy(new MyClient());
// Set the expected return value
PowerMockito.doReturn(20).when(classUnderTest, "myPrivateMethod", anyString(), anyInt());
// This is very important. Otherwise, it will not work
classUnderTest.myPrivateMethod();
// Setting the private field value as someValue:
Whitebox.setInternalState(classUnderTest, "privateField", someValue);
最后,您可以通过以下方式验证您的私有方法:
String msg = Whitebox.invokeMethod(obj, "privateMethodToBeTested", "param1");
Assert.assertEquals(privateMsg, msg);
Or
如果classUnderTest私有方法不返回值,但它设置了另一个私有字段,则可以获取该私有字段值以查看其设置是否正确:
// To get the value of a private field
MyClass obj = Whitebox.getInternalState(classUnderTest, "foo");
assertThat(obj, is(notNull(MyClass.class))); // Or test value
从测试框架测试Java私有方法的最佳合法方法是在方法上添加@VisibleForTesting注释,因此相同的方法将像公共方法一样在测试框架中可见。
如果您的测试类与应该测试的类在同一个包中呢?
当然,在另一个目录中,源代码使用src&classes,测试类使用test/src和test/classes。让类和测试/类位于类路径中。
您可以关闭反射的Java访问限制,这样私有就没有什么意义了。
setAccessible(true)调用实现了这一点。
唯一的限制是ClassLoader可能不允许您这样做。
有关在Java中实现这一点的方法,请参阅颠覆单元测试的Java访问保护(Ross Burton)。