JUnit:是否可以模拟在全局变量的初始化中调用的静态方法?
JUnit: Is it possible to mock a static method called within the initialization of a global variable?
在 Java 中,我有一个 class 例如
public class A {
private final Map<Integer, String> steps = ImmutableMap.of(
1, "one"
);
public String getStepOne() {
return steps.get(1);
}
}
现在我需要在单元测试中以某种方式模拟这个全局变量。不幸的是,我被告知要避免出于测试目的而对被测 class 的源代码进行任何更改,尤其是简单地提供 getter 并不是一个令人满意的解决方案。
我的尝试是像
一样模拟静态方法调用
@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
”。我怀疑如果从全局变量的初始化调用它们,那么以这种方式模拟静态方法调用是不可能的......有人知道是否有任何方法可以模拟这个变量(正如我所说, [=32 没有变化=] A
)?
============编辑==================
好吧,我同意通常模拟不可变映射没有多大意义,但实际上,映射看起来更像这样:
private final Map<Integer, B> steps = ImmutableMap.of(
1, new B()
);
而我真正需要的是模拟 B 类型的对象,它是值之一,因为它在 class 的进一步方法中通过 steps.get(...)
.
一个纯粹的 Java 解决方案可能是在 @Before
方法中使用反射。诀窍是首先摆脱 final
属性,然后再更改值。请参阅第一个答案:Change private static final field using Java reflection。同样适用于非静态成员。
在此处查看此 post 的修改代码:Java reflection example to change final member
在 Java 中,我有一个 class 例如
public class A {
private final Map<Integer, String> steps = ImmutableMap.of(
1, "one"
);
public String getStepOne() {
return steps.get(1);
}
}
现在我需要在单元测试中以某种方式模拟这个全局变量。不幸的是,我被告知要避免出于测试目的而对被测 class 的源代码进行任何更改,尤其是简单地提供 getter 并不是一个令人满意的解决方案。 我的尝试是像
一样模拟静态方法调用@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
”。我怀疑如果从全局变量的初始化调用它们,那么以这种方式模拟静态方法调用是不可能的......有人知道是否有任何方法可以模拟这个变量(正如我所说, [=32 没有变化=] A
)?
============编辑==================
好吧,我同意通常模拟不可变映射没有多大意义,但实际上,映射看起来更像这样:
private final Map<Integer, B> steps = ImmutableMap.of(
1, new B()
);
而我真正需要的是模拟 B 类型的对象,它是值之一,因为它在 class 的进一步方法中通过 steps.get(...)
.
一个纯粹的 Java 解决方案可能是在 @Before
方法中使用反射。诀窍是首先摆脱 final
属性,然后再更改值。请参阅第一个答案:Change private static final field using Java reflection。同样适用于非静态成员。
在此处查看此 post 的修改代码:Java reflection example to change final member