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

77

Я хочу смоделировать статический метод 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"); Gives compiler error that mockPartial not available, which I got from http://code.google.com/p/powermock/wiki/MockitoUsage.

Ваш Ответ

1   ответ
111

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

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

ОтJavadoc:

Creates class mock with a specified strategy for its answers to interactions. It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems. It is the default answer so it will be used only when you don't stub the method call.

default Стратегия создания заглушек по умолчанию состоит в том, чтобы просто возвращать null, 0 или false для методов объекта, числа и логических значений. Используя перегрузку в 2 аргумента, вы говорите: «Нет, нет, нет, по умолчанию используйте этот подкласс ответа». Метод ответа, чтобы получить значение по умолчанию. Он возвращает Long, поэтому, если у вас есть статические методы, которые возвращают что-то несовместимое с 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.

Хм ... Сорта выглядит так. Может быть, PowerMockito выполняет PowerMock для вас? Мне тоже интересно об этом.
Но что, если мне нужно быть уверенным, что какой-то статический метод вызывается с точными аргументами?
@PrepareForTest аннотация должна быть классом, которыйcalls статический метод, а не класс, в котором находится статический метод.
Есть ли необходимость в повторном воспроизведении?
@el_tomato - В моем примере были только методы без аргументов, но вы, как обычно, использовали бы совпадения. Увидеть:docs.mockito.googlecode.com/hg/latest/org/mockito/Matchers.html

Похожие вопросы