Jmockit非常强大,但有时我无法理解它背后的作用,所以我有一个关于jmockit的问题。希望这里经验丰富的程序员可以帮助对这种情况有所启发:)
我在两个单独的文件中有以下两个类:
public class SmallClass {
String a;
SmallClass(String arg) throws Exception {
a = arg;
}
public String getString() {
return a;
}
}
和
public class BigClass {
private static final SmallClass smallClass;
static {
try {
smallClass = new SmallClass("dummy");
} catch (Exception e) {
throw new IllegalStateException("Could not initialized", e);
}
}
public static String getString() {
return smallClass.getString();
}
}
现在,我有一个类来测试BigClass:
public class BigClassTest {
@Test
public void testGet() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
@Mock
public void $init(String string) throws Exception {
//Do nothing
}
@Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
}
@Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
@Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
}
}
如果我独立运行每一个,那么它们都会通过。但是,如果我运行整个测试文件,那么第一个测试将失败:
java.lang.NoClassDefFoundError: Could not initialize class BigClass
我也试过在每次测试之后拆掉模拟器,但它没有帮助:
public class BigClassTest {
MockUp<SmallClass> smallClassMockUp;
@Test
public void testGet() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
@Mock
public void $init(String string) throws Exception {
//Do nothing
}
@Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
smallClassMockUp.tearDown();
}
@Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
@Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
smallClassMockUp.tearDown();
}
}
任何帮助将不胜感激。提前谢谢!
答案 0 :(得分:0)
NoClassDefFoundError
的出现,在这种情况下,并不是因为JVM(它曾经)找不到类,而是因为它的静态初始化失败了(通过抛出异常或错误)执行静态初始化程序)。一旦发生这种情况,该类将处于无效/未初始化状态,并且不能再在同一JVM实例中使用。
供参考,请参阅JLS中的"Initialization of classes and interfaces"部分。
另请注意,测试执行的顺序不一定是它们在测试类中出现的文本顺序。在这里,testException
(第二次测试)首先运行。因此,当testGet
运行时,该类无效,JVM会抛出错误。