Насмешки, не вызываемые статическими членами, использующими PowerMockito - PullRequest
0 голосов
/ 27 апреля 2019

Я пытаюсь смоделировать Impl, который содержит 2 статических члена A, B и статический метод Utils.SomeMethod. Сначала я пытался смешать PowerMock и Mockito, но не был уверен, что это вызывает проблему, поэтому я изменил все ссылки на PowerMockito. Я получаю сбои модульного теста, которые не вызывают mocks. если я уберу статику и просто использую Mockito, все тесты пройдут успешно.

Вот краткое описание проблемы.

class Impl {

static A a;

static B b;

private static final String s = Utils.SomeMethod();

void mainMethod() {

   a.aMethod("foo");
   b.bMethod("bar");

}

}

Итак, в моем модульном тесте у меня есть

@PowerMockIgnore({"javax.net.ssl.*" , "javax.crypto.*"})
@RunWith(PowerMockRunner.class)
@PrepareForTest({Utils.class})
public class ImplTest {

  A a;
  B b;
  @Captor
  ArgumentCaptor<String> argumentCaptor;

  @BeforeClass
  static public void setUp() {
    PowerMockito.mockStatic(Utils.class);
    PowerMockito.when(Utils.SomeMethod()).thenReturn("test"); // works
  }

  @Before
  public void before() {
    a = PowerMockito.mock(A.class);
    b = PowerMockito.mock(B.class);
    impl = PowerMockito.mock(Impl.class);
    impl.setA(a); // I tried @Mock and @InjectMocks but seemed to not work on statics, works with non static members
    impl.setB(b);
 }

   @Test
   public void test() {
      PowerMockito.when(a
        .aMethod(any(String.class))
        .thenReturn("hmm");

    PowerMockito.when(b.bMethod(any(String.class))
        .thenReturn("yo");

     impl.mainMethod();

    verify(a, times(1)).aMethod(argumentCaptor.capture());
    // fails that 0 times mock was invoked 
   }   

}

Ответы [ 2 ]

0 голосов
/ 28 апреля 2019

Я хотел бы предложить использовать Mockito для большинства тестовых макетов и использовать PowerMockito только при работе с некоторыми статическими методами.С небольшими изменениями ваш тестовый код работал нормально:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Utils.class })
public class ImplTest {

    @Mock
    A a;

    @Mock
    B b;

    @Captor
    ArgumentCaptor<String> argumentCaptor;

    @BeforeClass
    static public void setUp() {
        PowerMockito.mockStatic(Utils.class);
        Mockito.when(Utils.SomeMethod()).thenReturn("test"); // works
    }

    Impl impl;

    @Before
    public void before() {
        Impl.setA(a);
        Impl.setB(b);

        impl = new Impl();
    }

    @Test
    public void test() {
       Mockito
            .when(a.aMethod(Matchers.any(String.class)))
            .thenReturn("hmmm");

       Mockito
            .when(b.bMethod(Matchers.any(String.class)))
            .thenReturn("yo");

      impl.mainMethod();

      Mockito.verify(a, Mockito.times(1)).aMethod(argumentCaptor.capture());
      Assert.assertEquals("foo", argumentCaptor.getValue());

      Mockito.verify(b, Mockito.times(1)).bMethod(argumentCaptor.capture());
      Assert.assertEquals("bar", argumentCaptor.getValue());
    }

}

Обратите внимание, что если A и B определены как статические, они должны быть внедрены в класс, а не в отдельные экземпляры.

@InjectMocks не будет работать в этом контексте, так как для него требуется другой Runner.Пожалуйста, взгляните на эту статью Разница между @Mock и @ InjectMocks

0 голосов
/ 27 апреля 2019

Насколько я понимаю, вы издеваетесь Impl, но вам следует создать его экземпляр, если вы хотите, чтобы mainMethod вызывал ваши статические методы. Кроме того, вы инициализируете argumentsCaptor где-нибудь в вашем коде?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...