In Java, I have a class like for example
public class A {
private final Map<Integer, String> steps = ImmutableMap.of(
1, "one"
);
public String getStepOne() {
return steps.get(1);
}
}
Now I need to somehow mock this global variable in a unit test. Unfortunately, I was told to avoid any changes in source code of the tested class for testing purposes, especially, simply providing a getter wouldn't be a satisfying solution. My attempt was to mock the static method call like
@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());
}
}
But this doesn't work, it prints "one
" and not "NEW ONE
". I suspect that mocking static method calls this way isn't possible if they are called from the initialization of a global variable ... does somebody know if there is any way to mock this variable (as I said, without changes in class A
)?
============ EDIT ==================
Well, I agree that generally it does not make much sense to mock an immutable map, but actually, the map looks more like this:
private final Map<Integer, B> steps = ImmutableMap.of(
1, new B()
);
and what I actually need, is to mock the object of type B, which is one of the values, because it is accessed in further methods of the class via steps.get(...)
.
A pure Java solution might be to use reflection in the @Before
method. The trick is to get rid of the final
property at first, and then to change the value. See the 1st answer of this: Change private static final field using Java reflection. Same should work for non static members.
See the modified code from this post here: Java reflection example to change final member