2016-08-25 4 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 фактически класс Lib третья стороны, что я не имею никакого контроля, который его делает статическую инициализацию, которая потерпит неудачу при тестировании env.

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

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

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

Я знаю, что могу использовать MockUp<Trouble>, чтобы избавиться от статического инициализатора, но я понятия не имею, как использовать его в случае, если, как я хочу (в моем реальном случае) иметь возможность различать две новые экземпляры (созданные в SysUnderTest) и проверяют их вызовы. Я пробовал разные способы, но все они не смогли с каким-то причинам

  1. Добавление new MockUp<Trouble>(){@Mock void $clinit(){} }; в @Before/@BeforeClass, и держать @Mocked Trouble trouble;. Это, похоже, не работает, потому что макет действие происходит после загрузки DummyTest класса, который будет загружаться (немодифицированный) Trouble класса, который будет бросать исключение во время статической инициализации

  2. Добавления нового Макета в TestSuite и вызове DummyTest в ванной, аналогичная проблема, как 1.

  3. Просто введите поведение возвращаемого 20, 30 в поддельный класс и удалите использование Expectations/Verifications, но у меня нет способа проверить, какой экземпляр вызывается с помощью какого параметра.

Есть ли лучший способ решить мою проблему? На самом деле я бы хотел использовать Expectaitons/Verifications, все, что я хочу, это способ отключить статический инициализатор во время модульного теста.

ответ

2

Используйте stubOutClassInitialization, чтобы изменить статическую инициализацию издеваемого класса на пустой метод при использовании Mocked.

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

Не могу себе представить, что я пропустил эту функцию! Он делает именно то, что я ожидаю! –

+0

Рад получить легкий ответ. :) – pmcevoy12