Конструктор с использованием Powermock для класса, который необходимо протестировать - PullRequest
0 голосов
/ 17 июня 2019

Я могу смоделировать вызов конструктора, используя powermock из класса, который я хочу протестировать. Это работает, когда я добавляю класс, который хочу протестировать в @PrepareForTest. Но как только я добавляю свой класс туда, даже когда тестовые примеры проходят, покрытие показывается как 0 в плагине покрытия.

Когда я удаляю свой класс из @PrepareForTest, конечно, покрытие начинает обнаруживаться для других тестовых случаев, но тестовый случай, в котором я должен смоделировать вызов конструктора, завершается неудачей. Не уверен, что с этим делать.

Class A
{
   MyObject o;
   A(){
     //some other code
     o = new MyObject();
     //some other code
   }

  public void process(){
    //some code

}

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
Class TestA{

  @Test
  public void test1()
  {
    MyObject mocked = Mockito.mock(MyObject.class);
 PowerMockito.whenNew(MyObject.class).withNoArguments().thenReturn(mocked);
  A a = new A();
  a.process();
  //Assert as per test case

 }

}

В инструменте покрытия покрытие отображается как 0, однако модульное тестирование прошло, и я проверил в режиме отладки, что оно покрывает все операторы класса А.

Ответы [ 2 ]

1 голос
/ 21 июня 2019

В инструменте покрытия покрытие отображается как 0, однако модульное тестирование прошло, и я проверил в режиме отладки, что оно покрывает все операторы класса А.

Инструменты покрытия полагаются на манипулирование исполняемым байтовым кодом.

То же самое происходит с PowerMock, когда вы издеваетесь над статическим / новым.

Это может быстро привести к всевозможным проблемам. Для JaCoCo, кажется, есть решение вокруг автономного инструментария . Где, я также помню: какой-то другой человек спросил об этом некоторое время назад, и в конце концов сдался, потому что он также не мог заставить работать «автономные инструменты».

Для любой другой среды я должен повторить старый совет: подумайте о том, чтобы потратить свое время на то, чтобы научиться писать простой в тестировании код. Потому что, если вы сделаете это, вам не нужно будет использовать PowerMock (ito) для его проверки.

Ваш код сложно протестировать из-за этого оператора new() в конструкторе. Просто не делай этого. Либо используйте внедрение зависимостей через @InjectMocks, либо используйте конструктор только для тестирования, который принимает требуемый объект.

Длинная история: когда вы пишете свой новый код и думаете, что вам нужен PowerMock для его проверки, вы делаете что-то не так.

0 голосов
/ 17 июня 2019

Я думаю, что вы можете обойтись без Powermock здесь. Если вы шпионите за классом A и издеваетесь над добытчиком, вы должны получить тот же результат и, скорее всего, ваш страховой полис будет правильным:

@Test
public void test1(){
    MyObject mocked = Mockito.mock(MyObject.class);
    A spyA = Mockito.spy(new A());
    doReturn(mocked).when(spyA).getMyObject();
    ...
}
...