使用jmockit模拟抛出错误的构造函数:NoClassDefFoundError

时间:2016-06-24 05:00:12

标签: java unit-testing testing noclassdeffounderror jmockit

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();
    }
}

任何帮助将不胜感激。提前谢谢!

1 个答案:

答案 0 :(得分:0)

NoClassDefFoundError的出现,在这种情况下,并不是因为JVM(它曾经)找不到类,而是因为它的静态初始化失败了(通过抛出异常或错误)执行静态初始化程序)。一旦发生这种情况,该类将处于无效/未初始化状态,并且不能再在同一JVM实例中使用。

供参考,请参阅JLS中的"Initialization of classes and interfaces"部分。

另请注意,测试执行的顺序不一定是它们在测试类中出现的文本顺序。在这里,testException(第二次测试)首先运行。因此,当testGet运行时,该类无效,JVM会抛出错误。