如何禁用静态初始化程序?
How to disable static initializer?
假设我的测试系统如下所示:
public class SysUnderTest {
public int foo() {
Trouble trouble1 = new Trouble();
Trouble trouble2 = new Trouble();
return trouble1.water(1) + trouble2.water(2);
}
}
测试看起来像
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);
}};
}
}
然而,Trouble
实际上是一个我无法控制的第 3 方库 class,它进行静态初始化,这将在测试环境时失败。
public class Trouble {
static {
troubleInitialize();
};
public int water(int i) {
return 0;
}
private static void troubleInitialize() {
throw new RuntimeException("Trouble");
}
}
我知道我可以使用 MockUp<Trouble>
来摆脱静态初始值设定项,但我不知道如何使用它以防万一我想(在我的现实情况下)能够区分两个新实例(在 SysUnderTest 中创建)并验证它们的调用。我尝试了不同的方法,但由于某些原因都失败了
在@Before
/@BeforeClass
中加一个new MockUp<Trouble>(){@Mock void $clinit(){} };
,保留@Mocked Trouble trouble;
。它似乎不起作用,因为模型操作发生在加载 DummyTest
class 之后,它将加载(未修改)Trouble
class,这将在静态初始化期间抛出异常[=26] =]
在TestSuite
中添加新的Mockup并在suite中调用DummyTest
,类似问题1.
简单的把返回20, 30
的行为放到fake的class里,去掉Expectations/Verifications
的用法但是我没办法验证调用的是哪个实例用什么参数。
有没有更好的方法来解决我的问题?实际上我想继续使用 Expectaitons/Verifications
,我想要的只是在单元测试期间禁用静态初始化器的某种方法。
在使用 Mocked 时,使用 stubOutClassInitialization 将 mocked class 的静态初始化更改为空方法。
@Mocked(stubOutClassInitialization=true) Trouble trouble;
假设我的测试系统如下所示:
public class SysUnderTest {
public int foo() {
Trouble trouble1 = new Trouble();
Trouble trouble2 = new Trouble();
return trouble1.water(1) + trouble2.water(2);
}
}
测试看起来像
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);
}};
}
}
然而,Trouble
实际上是一个我无法控制的第 3 方库 class,它进行静态初始化,这将在测试环境时失败。
public class Trouble {
static {
troubleInitialize();
};
public int water(int i) {
return 0;
}
private static void troubleInitialize() {
throw new RuntimeException("Trouble");
}
}
我知道我可以使用 MockUp<Trouble>
来摆脱静态初始值设定项,但我不知道如何使用它以防万一我想(在我的现实情况下)能够区分两个新实例(在 SysUnderTest 中创建)并验证它们的调用。我尝试了不同的方法,但由于某些原因都失败了
在
@Before
/@BeforeClass
中加一个new MockUp<Trouble>(){@Mock void $clinit(){} };
,保留@Mocked Trouble trouble;
。它似乎不起作用,因为模型操作发生在加载DummyTest
class 之后,它将加载(未修改)Trouble
class,这将在静态初始化期间抛出异常[=26] =]在
TestSuite
中添加新的Mockup并在suite中调用DummyTest
,类似问题1.简单的把返回
20, 30
的行为放到fake的class里,去掉Expectations/Verifications
的用法但是我没办法验证调用的是哪个实例用什么参数。
有没有更好的方法来解决我的问题?实际上我想继续使用 Expectaitons/Verifications
,我想要的只是在单元测试期间禁用静态初始化器的某种方法。
在使用 Mocked 时,使用 stubOutClassInitialization 将 mocked class 的静态初始化更改为空方法。
@Mocked(stubOutClassInitialization=true) Trouble trouble;