PowerMockito макет одного статического метода и возвращаемого объекта

Я хочу смоделировать статический метод m1 из класса, который содержит 2 статических метода, m1 и m2. И я хочу, чтобы метод m1 возвращал объект.

Я попробовал следующее

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() {
         @Override
         public Long answer(InvocationOnMock invocation) throws Throwable {
            return 1000l;
         }
      });

Это вызывает и m1, и m2, у которых другой тип возвращаемого значения, поэтому он дает ошибку несоответствия возвращаемого типа.

2) PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l); Но это не вызывается, когда m1 выполняется.

3) PowerMockito.mockPartial(Static.class, "m1"); Выдает ошибку компилятора, что mockPartial недоступен, который я получил с http://code.google.com/p/powermock/wiki/MockitoUsage.

1 ответ

То, что вы хотите сделать, это комбинация части 1 и всех 2.

Вам необходимо использовать PowerMockito.mockStatic, чтобы включить статическое моделирование для всех статических методов класса. Это означает, что их можно заглушить, используя синтаксис when-thenReturn.

Но перегрузка mockStatic с двумя аргументами, которую вы используете, предоставляет стратегию по умолчанию для того, что должен делать Mockito/PowerMock, когда вы вызываете метод, который вы не указали явно на экземпляре mock.

Из Javadoc:

Создает макет класса с указанной стратегией для его ответов на взаимодействия. Это довольно продвинутая функция, и, как правило, она не нужна для написания достойных тестов. Однако это может быть полезно при работе с устаревшими системами. Это ответ по умолчанию, поэтому он будет использоваться только тогда, когда вы не заглушите вызов метода.

Стратегия по умолчанию для заглушки по умолчанию состоит в том, чтобы просто возвращать null, 0 или false для методов объекта, числа и логических значений. Используя перегрузку в 2 аргумента, вы говорите: "Нет, нет, нет, по умолчанию используйте метод ответа этого подкласса ответа, чтобы получить значение по умолчанию. Он возвращает Long, поэтому если у вас есть статические методы, которые возвращают что-то несовместимое с Долго есть проблема.

Вместо этого используйте 1-аргументную версию mockStatic, чтобы включить заглушки статических методов, затем используйте when-thenReturn, чтобы указать, что делать с конкретным методом. Например:

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

class ClassWithStatics {
  public static String getString() {
    return "String";
  }

  public static int getInt() {
    return 1;
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic {
  @Test
  public void test() {
    PowerMockito.mockStatic(ClassWithStatics.class);

    when(ClassWithStatics.getString()).thenReturn("Hello!");

    System.out.println("String: " + ClassWithStatics.getString());
    System.out.println("Int: " + ClassWithStatics.getInt());
  }
}

Статический метод со строковым значением является заглушкой для возврата "Hello!", В то время как статический метод со внутренним значением использует заглушку по умолчанию, возвращая 0.

Другие вопросы по тегам