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.