JUnit: возможно ли смоделировать статический метод, вызываемый при инициализации глобальной переменной? - PullRequest
0 голосов
/ 14 октября 2019

В Java у меня есть класс, например,

public class A {

  private final Map<Integer, String> steps = ImmutableMap.of(
      1, "one"
  );

  public String getStepOne() {
    return steps.get(1);
  }
}

Теперь мне нужно каким-то образом смоделировать эту глобальную переменную в модульном тесте. К сожалению, мне сказали избегать каких-либо изменений в исходном коде тестируемого класса для целей тестирования, особенно, просто предоставление получателя не будет удовлетворительным решением. Я пытался смоделировать статический вызов метода, например

@RunWith(PowerMockRunner.class)
@PrepareForTest({A.class, ImmutableMap.class})
public class ATest {

  private A subj = new A();

  @Before
  public void setUp() {
    PowerMockito.mockStatic(ImmutableMap.class);
    ImmutableMap<Object, Object> mockedMap = ImmutableMap.of(1, "NEW ONE");
    BDDMockito.given(ImmutableMap.of()).willReturn(mockedMap);
  }

  @Test
  public void testGetStepOne() {
    System.out.println(subj.getStepOne());
  }
}

Но это не работает, он печатает "one", а не "NEW ONE". Я подозреваю, что поддельные вызовы статических методов таким способом невозможны, если они вызываются из инициализации глобальной переменной ... Кто-нибудь знает, есть ли способ смоделировать эту переменную (как я уже сказал, без изменений в классе * 1009? *)?

============ РЕДАКТИРОВАТЬ ==================

Хорошо, я согласен, что в общем случае нет смысла издеваться над неизменной картой, но на самом деле карта выглядит примерно так:

  private final Map<Integer, B> steps = ImmutableMap.of(
      1, new B()
  );

и что мне действительно нужно, так это издеваться над объектомтипа B, который является одним из значений, потому что к нему обращаются в других методах класса через steps.get(...).

1 Ответ

1 голос
/ 14 октября 2019

Чистым решением Java может быть использование отражения в методе @Before. Хитрость заключается в том, чтобы сначала избавиться от свойства final, а затем изменить значение. См. 1-й ответ: Изменить частное статическое конечное поле с помощью отражения Java . То же самое должно работать для нестатических членов. Смотрите модифицированный код из этого поста здесь: Пример отражения Java для изменения конечного члена

...