如何在没有powermock的情况下模拟静态方法

2022-08-31 20:18:45

在 JUnit 中进行测试时,我们有什么方法可以模拟静态 util 方法吗?

我知道Powermock可以模拟静态调用,但我不想使用Powermock。

有没有其他选择?


答案 1

(我假设你可以使用Mockito)我脑海中没有专门的内容,但是当涉及到这种情况时,我倾向于使用以下策略:

1) 在所测试的类中,将静态直接调用替换为对包级别方法的调用,该方法包装静态调用本身:

public class ToBeTested{

    public void myMethodToTest(){
         ...
         String s = makeStaticWrappedCall();
         ...
    }

    String makeStaticWrappedCall(){
        return Util.staticMethodCall();
    }
}

2)在测试时监视被测试的类,并模拟包装包级别方法:

public class ToBeTestedTest{

    @Spy
    ToBeTested tbTestedSpy = new ToBeTested();

    @Before
    public void init(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void myMethodToTestTest() throws Exception{
       // Arrange
       doReturn("Expected String").when(tbTestedSpy).makeStaticWrappedCall();

       // Act
       tbTestedSpy.myMethodToTest();
    }
}

这是我写的一篇关于间谍的文章,如果你需要更多的见解,包括类似的案例:sourceartists.com/mockito-spying


答案 2

当你有静态代码给你的单元测试带来麻烦时;所以你觉得你必须“嘲笑它”,你完全有这些选择:

  • 你转向PowerMock(ito)。工作正常。
  • 你转向JMockit。工作正常。
  • 如果你正在测试你自己编写的代码,你可能想退后一步,问问自己:“为什么我写了我现在觉得很难单元测试的代码?

换句话说:如果你想使用一个模拟框架,你必须使用上面列出的框架之一。一方面,这是绝对公平的。static是Java语言的一部分;那么为什么不使用一个允许你处理它的框架呢?

但是,当然:那么你的生产代码中仍然有静态调用。导致紧密耦合,并防止多态性

所以:如果你能摆脱静态调用(即使只是使用其他答案中建议的解决方法) - 那就更好了。如果没有:Mockito无能为力;你需要字节码操作的魔力,以及JVM代理。


推荐