jmockit和静态初始化

时间:2016-06-07 13:05:20

标签: java unit-testing jmockit

我们正在使用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才能阻止它被执行。

所以我们的问题:

  1. 即使在参数中将类声明为@Mocked,静态初始化代码仍然执行的预期行为是什么?

  2. 为什么上面的BeforeClass代码无法模拟Utils的静态初始化代码?

  3. 非常感谢你的帮助!

0 个答案:

没有答案