如何禁用静态初始化程序?

Adr*_*hum 1 jmockit

假设我的被测系统如下所示:

public class SysUnderTest {
    public int foo() {
        Trouble trouble1 = new Trouble();
        Trouble trouble2 = new Trouble();
        return trouble1.water(1) + trouble2.water(2);
    }
}
Run Code Online (Sandbox Code Playgroud)

测试看起来像

public class DummyTest {

    @Tested SysUnderTest sut;
    @Mocked Trouble trouble;

    @Test
    public void testTrouble() {
        new Expectations() {{
            trouble.water(anyInt); returns(10, 20);
        }};

        assertThat("mocked result", sut.foo(), is(30));

        new FullVerificationsInOrder() {{
            Trouble t1 = new Trouble();
            Trouble t2 = new Trouble();
            t1.water(1);
            t2.water(2);
        }};
    }
}   
Run Code Online (Sandbox Code Playgroud)

但是,Trouble实际上是我无法控制的第 3 方 lib 类,它执行静态初始化,但在测试 env 时会失败。

public class Trouble {
    static {
        troubleInitialize();
    };

    public int water(int i) {
        return 0;
    }

    private static void troubleInitialize() {
        throw new RuntimeException("Trouble");
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以MockUp<Trouble>用来摆脱静态初始值设定项,但我不知道如何使用它,因为我希望(在我的实际情况下)能够区分两个新实例(在 SysUnderTest 中创建)并验证他们的调用。我尝试了不同的方法,但由于某些原因都失败了

  1. new MockUp<Trouble>(){@Mock void $clinit(){} };@Before/ 中添加一个@BeforeClass,并保持@Mocked Trouble trouble;. 这似乎不起作用,因为模型操作发生在DummyTest类加载后,这将加载(未修改)Trouble类,该类将在静态初始化期间抛出异常

  2. 在 a 中添加新的 MockupTestSuite并调用insuite DummyTest,与 1 类似的问题。

  3. 简单地将返回的行为放在20, 30假类中,并删除使用Expectations/Verifications但我无法验证使用什么参数调用哪个实例。

有没有更好的方法来解决我的问题?实际上我想继续使用Expectaitons/Verifications,我想要的只是在单元测试期间禁用静态初始化程序的某种方法。

pam*_*voy 5

使用Mocked 时,使用stubOutClassInitialization模拟类的静态初始化更改为空方法。

@Mocked(stubOutClassInitialization=true) Trouble trouble;
Run Code Online (Sandbox Code Playgroud)