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 .

Відповіді:


135

Те, що ви хочете зробити, це поєднання частини 1 і всіх 2.

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

Але перевантаження двома аргументами mockStatic, яку ви використовуєте, надає стратегію за замовчуванням для того, що повинен робити Mockito / PowerMock, коли ви викликаєте метод, який ви явно не застосували до екземпляра mock.

З javadoc :

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

За замовчуванням стратегія заглушення за замовчуванням полягає в тому, щоб просто повернути значення null, 0 або false для методів з об'єктом, числом та логічним значенням. Використовуючи перевантаження 2-arg, ви говорите: "Ні, ні, ні, за замовчуванням використовуйте метод відповіді цього підкласу відповідей, щоб отримати значення за замовчуванням. Він повертає Long, тому, якщо у вас є статичні методи, які повертають щось несумісне з Довго, є проблема.

Замість цього використовуйте версію 1-arg mockStatic, щоб увімкнути заглушення статичних методів, а потім використовуйте, коли-тодіReturn, щоб вказати, що робити для конкретного методу. Наприклад:

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());
  }
}

Статичний метод, що має значення рядка, заглушується, щоб повернути "Привіт!", Тоді як статичний метод, що має значення "int", використовує "типову" за замовчуванням, повертаючи 0.


1
Чи немає необхідності перегравати?
Balaji Boggaram Ramanarayan

Хм ... сорта здається так. Можливо, PowerMockito відтворює PowerMock для вас? Мені також це цікаво.
djangofan

3
Але що, якщо мені потрібно бути впевненим, що якийсь статичний метод викликається з точними аргументами?
elTomato

6
@PrepareForTestАнотацій повинен бути класом , який викликає статичний метод, а не клас , де статичний метод є.
Hazel Troost

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