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


98

Я хочу издеваться над статическим методом 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 .

Ответы:


136

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

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

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

Из javadoc :

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

По умолчанию стратегии раскорчевки по умолчанию является просто вернуть NULL, 0 или ложно для объекта, количества и Булевозначных методы. Используя перегрузку с 2 аргументами, вы говорите: «Нет, нет, нет, по умолчанию используйте метод ответа этого подкласса Answer для получения значения по умолчанию. Он возвращает Long, поэтому, если у вас есть статические методы, которые возвращают что-то несовместимое с Давно, есть проблема.

Вместо этого используйте версию mockStatic с 1 аргументом, чтобы включить заглушку статических методов, а затем используйте 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.


1
Нет необходимости в воспроизведении?
Баладжи Боггарам Раманараян

Хм ... вроде как. Может быть, PowerMockito воспроизводит PowerMock за вас? Мне тоже интересно об этом.
djangofan

3
Но что, если мне нужно быть уверенным, что какой-то статический метод вызывается с точными аргументами?
elTomato

6
@PrepareForTestАннотаций должен быть классом , который вызывает статический метод, а не класс , где статический метод есть.
Hazel Troost

5
@HazelTroost - Нет, ОП прав. Это класс, содержащий статический метод, который следует подготовить к тестированию. Итак, @PrepareForTest(ClassWithStatics.class)правильно.
arry36
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.