使用PowerMock和TestNG模拟单个静态方法

5
class StaticClass {
  public static String a(){ return "a"; }
  public static String ab(){ return a()+"b"; }
}

我想要模拟 StaticClass::a,使其返回值为 "x",并且调用 StaticClass.ab() 的结果为 "xb"...

我在 PowerMock 和 TestNG 中感到非常困难...


我正在测试的确切代码:

class StaticClass {
    public static String A() {
        System.out.println("Called A");
        throw new IllegalStateException("SHOULD BE MOCKED AWAY!");
    }

    public static String B() {
        System.out.println("Called B");
        return A() + "B";
    }
}

@PrepareForTest({StaticClass.class})
public class StaticClassTest extends PowerMockTestCase {

    @Test
    public void testAB() throws Exception {
        PowerMockito.spy(StaticClass.class);
        BDDMockito.given(StaticClass.A()).willReturn("A");
        assertEquals("AB", StaticClass.B()); // IllegalStateEx is still thrown :-/
    }

}

我有以下的Maven依赖:

<artifactId>powermock-module-testng</artifactId>
and
<artifactId>powermock-api-mockito</artifactId>

1
你是否尝试按照PowerMock文档中所述的方式进行操作? - sigito
1
@sigito 是的!我会更新示例,向您展示我需要模拟的代码。 - Parobay
你可能已经丢失了 mockStatic 方法的调用。 - sigito
@sigito,你看,我不想嘲笑整个类,只是一个单独的静态方法... - Parobay
2个回答

10

为什么不尝试类似这样的东西:

PowerMockito.mockStatic(StaticClass.class);
Mockito.when(StaticClass.a()).thenReturn("x");
Mockito.when(StaticClass.ab()).thenCallRealMethod();

1
他正在使用TestNG而不是Mockito。 - DLight
2
如果方法返回空值(void),那怎么办?这仍然可能吗?如果我的静态类有20个静态方法,而我只想模拟其中一个方法,该怎么办? - Marquez
@Marquez 是的,对于void方法仍然是可能的。如果ab()是一个不返回任何内容的void方法,它可以像这样:PowerMockito.when(StaticClass.class, "ab").thenCallRealMethod(); - garykwwong

2

这听起来还不错。但说实话,我非常不喜欢通过字符串名称指定方法... 如果没有一个好的IDE,这将是一个恐怖的维护工作。有没有一种方式可以通过编写实际的Java代码进行模拟(换句话说:像普通方法一样模拟)? - Parobay
那是一个很好的观点。我认为你也可以通过使用spy来实现这一点。请参阅https://dev59.com/52445IYBdhLWcg3wcJ2O。 - abourg28

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接