2016-06-24 6 views
0

Jmockit은 매우 강력하지만 때로는 장면 뒤에 무엇이 있는지 이해할 수 없기 때문에 jmockit에 관한 질문이 있습니다. 희망 여기에 경험 많은 프로그래머는이 상황 :jmockit을 사용하여 오류를 throw하는 생성자 모방 : NoClassDefFoundError

에 대한 몇 가지 빛을 도울 수있는 내가 가진 두 개의 별도의 파일에 다음과 같은 두 개의 클래스 : 이제

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 (두 번째 테스트)이 먼저 실행됩니다. 따라서 testGet이 실행되면 클래스가 유효하지 않으며 JVM이 오류를 발생시킵니다.

+0

그렇다면 생성자가 정적 블록에서 예외를 throw하는 경우와 그렇지 않은 경우를 모두 테스트하기 위해 단위 테스트를 작성하는 방법은 무엇입니까? –

+0

정적 초기화가 실패한 테스트를 * 가질 필요가 없습니다. 'BigClass'의 정적 이니셜 라이저에있는'catch' 블록은 컴파일러를위한 것입니다. –