如何使用JUnit测试具有内部私有方法、字段或嵌套类的类?
仅仅为了能够运行测试而更改方法的访问修饰符似乎是不好的。
如何使用JUnit测试具有内部私有方法、字段或嵌套类的类?
仅仅为了能够运行测试而更改方法的访问修饰符似乎是不好的。
当前回答
还有另一种方法可以测试您的私有方法。
如果在运行配置中“启用断言”,则可以在方法本身内部对方法进行单元测试。例如
assert ("Ercan".equals(person1.name));
assert (Person.count == 2);
其他回答
Groovy有一个bug/特性,通过它可以调用私有方法,就像它们是公共的一样。因此,如果您能够在项目中使用Groovy,那么可以使用它来代替反射。查看此页面以获取示例。
如果您想测试不能更改代码的遗留应用程序的私有方法,Java的一个选项是jMockit,它将允许您创建对象的模拟,即使它们对类是私有的。
还有另一种方法可以测试您的私有方法。
如果在运行配置中“启用断言”,则可以在方法本身内部对方法进行单元测试。例如
assert ("Ercan".equals(person1.name));
assert (Person.count == 2);
对于C++(从C++11开始),将测试类添加为好友非常有效,不会破坏生产封装。
让我们假设我们有一些类Foo和一些真正需要测试的私有函数,还有一些类FooTest应该可以访问Foo的私有成员。然后我们应该写下以下内容:
// prod.h: some production code header
// forward declaration is enough
// we should not include testing headers into production code
class FooTest;
class Foo
{
// that does not affect Foo's functionality
// but now we have access to Foo's members from FooTest
friend FooTest;
public:
Foo();
private:
bool veryComplicatedPrivateFuncThatReallyRequiresTesting();
}
// test.cpp: some test
#include <prod.h>
class FooTest
{
public:
void complicatedFisture() {
Foo foo;
ASSERT_TRUE(foo.veryComplicatedPrivateFuncThatReallyRequiresTesting());
}
}
int main(int /*argc*/, char* argv[])
{
FooTest test;
test.complicatedFixture(); // and it really works!
}
如果您有一些遗留的Java应用程序,并且不允许更改方法的可见性,那么测试私有方法的最佳方法是使用反射。
在内部,我们使用助手来获取/设置私有和私有静态变量,以及调用私有和私有的静态方法。以下模式将允许您执行与私有方法和字段相关的任何操作。当然,您不能通过反射来更改私有静态final变量。
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
对于字段:
Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
笔记:TargetClass.getDeclaredMethod(methodName,argClasses)允许您查看私有方法。同样的事情也适用于getDeclaredField。需要setAccessible(true)才能与private一起玩。