2016-08-25 3 views
1

은 다음과 같습니다정적 이니셜 라이저를 비활성화하는 방법은 무엇입니까? 테스트중인 내 시스템을 가정

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 자 LIB 클래스입니다 보이는 그것을 테스트 환경에서 실패 할 정적 초기화를 수행합니다. 두 새를 구별 할 수

public class Trouble { 
    static { 
     troubleInitialize(); 
    }; 

    public int water(int i) { 
     return 0; 
    } 

    private static void troubleInitialize() { 
     throw new RuntimeException("Trouble"); 
    } 
} 

는 내가 정적 초기화 없애 MockUp<Trouble>을 사용할 수 있습니다 알고 있지만 내가 어떻게 (내 실제 경우)에 원하는 경우에 그것의 사용을 만드는 아무 생각이 없다 인스턴스 (SysUnderTest에서 생성됨)를 호출하고 해당 호출을 확인합니다. 나는 다른 방법을 시도했지만 모두 @Before/@BeforeClassnew MockUp<Trouble>(){@Mock void $clinit(){} };를 추가하는 몇 가지 이유

  1. 에 실패하고 @Mocked Trouble trouble;을 유지한다. 모형 조치가 TestSuite의 새로운 목업 추가 정적 초기화

  2. 동안 예외를 던져 스위트에서 DummyTest를 호출합니다 (수정되지 않은) Trouble 클래스를로드 할의 DummyTest 클래스가로드 된 후 발생 때문에, 작동하지 않는 것 같다 유사한 문제로 1

  3. 가짜 클래스에 20, 30을 반환하는 동작을 넣고 Expectations/Verifications의 사용을 제거하지만 어떤 인스턴스가 어떤 매개 변수로 호출되는지 확인할 방법이 없습니다.

내 문제를 해결하는 더 좋은 방법이 있습니까? 사실 Expectaitons/Verifications을 계속 사용하고 싶습니다. 단위 테스트 중에 static initializer를 비활성화하는 방법이 필요합니다.

답변

2

Mocked를 사용할 때 stubOutClassInitialization을 사용하면 조롱 된 클래스의 정적 초기화를 빈 메소드로 변경할 수 있습니다.

@Mocked(stubOutClassInitialization=true) Trouble trouble; 
+0

이 기능을 놓친 것 같지 않습니다. 그것은 내가 기대하는 바를 정확하게 수행합니다! –

+0

쉬운 답변을 기쁘게 생각합니다. :) – pmcevoy12