我们正在使用Jmockit进行单元测试,我们对模拟类的静态初始化有疑问。当我们通过在函数参数中将它声明为(@Mocked final)来模拟一个类时,我们期望这个类的静态初始化也被模拟,但事实并非如此。这是一个显示问题的示例。
class TmpClass {
static public int method1(){
System.out.println("AClass method1 is called");
return 10;
}
static public int method2(){
System.out.println("AClass method2 is called");
return 20;
}
}
class Utils {
static public int sInt = TmpClass.method1();
public int pInt = TmpClass.method2();
static public int method(){
System.out.println("Should NOT be called when Utils is mocked.");
return 1000;
}
}
class ClassToTest {
public int foo(){
return Utils.method();
}
public int goo(){
return Utils.sInt;
}
}
public class TestPost {
@Test
public void test(@Mocked final Utils mocked) {
System.out.println("This should show 0 as expected since Utils is mocked: " + new ClassToTest().foo());
System.out.println("This should show 0 as expected since Utils is mocked: " + mocked.pInt);
System.out.println("This should be 0 but it is not: " + new ClassToTest().goo());
System.out.println("This should be 0 but it is not: " + mocked.sInt);
}
}
这里有一个我们要测试的ClassToTest。它取决于一个名为Utils的类。所以我们通过在函数参数中声明(@Mocked fine Utils mocked)来模拟Utils。在这之后, 1.静态方法Utils.method按预期进行模拟。所以ClassToTest.foo按预期返回0。 但是静态变量Utils.sInt没有被模拟。实际上调用了TmpClass.method1,并且为Utils.sInt分配了10。 3.成员变量Utils.pInt被模拟。 mocked.pInt显示为0预期。
由于上面的2,调用了TmpClass.method1。由于我们不想在我们的测试环境中执行TmpClass,我们接下来要做的就是将以下内容放入TestPost。
@BeforeClass
static public void init(){
new MockUp<Utils>(){
@Mock
public void $clinit(){
}
};
}
但这不起作用。仍然调用TemClass.method1!我们必须直接模拟TmpClass才能阻止它被执行。
所以我们的问题:
即使在参数中将类声明为@Mocked,静态初始化代码仍然执行的预期行为是什么?
为什么上面的BeforeClass代码无法模拟Utils的静态初始化代码?
非常感谢你的帮助!