我最近开始研究TDD for exisitng项目并面临几个问题,其中一个问题如下所述
我有一个私有变量要在测试类中进行模拟,变量如下所示
private Class<XYZ> cls = XYZ.class;
以后这个“cls”变量用作className
之一的方法的arugmentprivate List create(Class className, Object objectTO, List<String> names)
我知道私有变量可以被嘲笑 我通过以下步骤
在我的测试用例中模拟了私有变量java.lang.reflect.Field;
Field field = PowerMockito.field(XYZ.class,"cls");
field.set(XYZ.class, "objectOfXYZClass");
当我运行我的测试课时,我遇到了错误
java.lang.IllegalArgumentException: Can not set java.lang.Class field com.tools.XYZ.cls to java.lang.Class
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:680)
请有人帮我解决这个问题,让我知道我错过了什么。
PS:我使用@preparefortest
并提及了所有必需的类,并使用@runwith(powermockrunner.class)
运行我的测试类
答案 0 :(得分:2)
您的单元测试错误。它们不是测试内部实现(如字段或私有方法)。
单元测试通常只应执行以下操作:
换句话说:您非常希望仅测试“被测试类”的外部可见行为。而且你知道:如果你的班级没有外部可见的行为 - 为什么你有这个行为呢?!
当然,有时这不是“足够好”。在这种情况下,你通常会做什么:你转向一些模拟框架(如EasyMock或Mockito)来创建模拟的对象。在实例化测试中的类(称为依赖注入)时,可以使用这些模拟。通过这样做,您可以完全控制您所测试的课程;例如,您可以验证您的模拟是否会看到您期望的那些方法调用。
所以,长话短说:是的,有可能以某种方式访问正在测试的类的字段。但这导致了不值得这个名字的单元测试。因为一旦您开始重构代码的内部,这些测试就会中断。从这个意义上讲:这样的测试只能证明您当前的实现按预期工作。但是每当你改变某些东西时,你将不得不返工(可能更大!)零件或你的测试代码。
最后:编写单元测试是一项需要学习的技能。达到目标的最佳资源之一是videos。
答案 1 :(得分:1)
new Thread(new Runnable() {
@Override
public void run() {
///background calculations
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
//main thread task to update user interface
}
});
}
}).start();
放入集合,类的实例。不上课。因为您将字符串“objectOfXYZClass”设置为对象。不进入班级;) 我要添加
field.set(instanceOfClassXYZ, "")