2016-06-24 12 views
0

Jmockitは非常に強力ですが、ときどきシーンの背後で何ができるか分からないことがあるので、jmockitに関する質問があります。うまくいけば、ここでの経験豊富なプログラマは、このような状況にいくつかの光を当てる助けることができる:)jmockitを使ってコンストラクタをモックしてエラーをスローする:NoClassDefFoundError

私は2つの別々のファイルに次の二つのクラスがあります。今

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

を、I 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

このような場合は、クラスがJVMによって検出されなかったためではありませんが、その静的な初期化に失敗したためです(実行から例外またはエラーをスローすることによって)。静的初期化子)。これが発生すると、クラスは無効/未初期化状態になり、もはや同じJVMインスタンスでは使用できなくなります。

参考までに、JLSの"Initialization of classes and interfaces"を参照してください。

また、テストの実行順序は必ずしもテストクラスに表示されるテキスト順とは限りません。ここでは、testException(2番目のテスト)が最初に実行されます。したがって、testGetが実行されると、クラスは無効であり、JVMはエラーをスローします。

+0

したがって、スタティックブロックに例外がスローされるケースとそうでないケースの両方をテストするために、単体テストを作成するにはどうすればよいですか? –

+0

静的初期化が失敗するテストは*必要ありません。 'BigClass'の静的初期化子の' catch'ブロックはコンパイラのためのものであることに注意してください。 –

関連する問題