繁体   English   中英

JUnit:是否可以模拟在全局变量初始化中调用的 static 方法?

[英]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 不会是一个令人满意的解决方案。 我的尝试是模拟 static 方法调用,例如

@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 ”。 我怀疑如果从全局变量的初始化中调用 mocking static 方法调用这种方式是不可能的......有人知道是否有任何方法可以模拟这个变量(正如我所说,没有改变A ) ?

============ 编辑 ===================

好吧,我同意通常模拟不可变的 map 没有多大意义,但实际上,map 看起来更像这样:

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

而我真正需要的是模拟 B 类型的 object,这是值之一,因为它可以通过steps.get(...)在 class 的进一步方法中访问。

纯粹的 Java 解决方案可能是在@Before方法中使用反射。 诀窍是首先摆脱final属性,然后更改值。 请参阅第一个答案: 使用 Java 反射更改私有 static 最终字段 同样适用于非 static 成员。 在此处查看此帖子的修改代码: Java 反射示例以更改最终成员

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM