是否可以使用 Mockito 模拟静态和无效的方法? [英] Is it possible to mock a method that is both static and void using Mockito?

查看:132
本文介绍了是否可以使用 Mockito 模拟静态和无效的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图避免在这里使用 PowerMockito.我们有遗留代码,其中包含静态和无效的方法,并且有需要模拟它们的测试.有没有办法做到这一点,或者重构遗留代码是这里的唯一方法?

I'm trying to avoid using PowerMockito here. We have legacy code which contains methods that are both static and void and there are tests which need to mock them. Is there a way to do it or is refactoring legacy code the only way here?

class MySample {
       public static void sampleMethod(String argument){
                //do something
       }
}

如果我使用一般的 MockStatic 语法,它会要求我返回一些东西:

If I use the general MockStatic syntax, it asks me to return something:

MockedStatic <MySample> sampleMock = Mockito.mockStatic( MySample.class );
sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)));

异常:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at com.mytests.Test.setMock(Test.java:35)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed

请注意,我希望模拟一个既是静态又是空的方法.

Please note that I'm looking to mock a method that is BOTH static and void.

推荐答案

当模拟方法被调用时,你希望发生什么?

What do you want to happen when the mocked method gets called?

默认行为是什么都不发生.通过调用 sampleMock.when(),您表明您想从默认行为更改为其他行为.Mockito 正在抱怨,因为你没有接着调用 then___() 来指定应该发生的事情.

The default behavior is that nothing happens. By calling sampleMock.when(), you indicated that you wanted to change from the default behavior to something else. Mockito is complaining because you didn't then follow that up with a call to then___() to specify what should happen instead.

我能想到您可能希望发生的一些不同的事情:

There are a few different things I can think of that you might want to have happen:

如前所述,这是默认行为,所以如果这就是你想要的,你可以删除第二行,它应该可以工作.但是,如果你真的需要一个 when 调用(例如用于参数捕获),你可以用一个空的 thenAnswer 结束该行:

As previously stated, this is the default behavior, so if this is all you want, you can just remove the second line and it should work. But, if you really need to have a when call (e.g. for argument capture), you can instead finish off the line with an empty thenAnswer:

sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
    .thenAnswer(invocation -> null);

2.调用真正的方法

sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
    .thenCallRealMethod();

3.做点别的

sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
    .thenAnswer(invocation -> {
        // insert code to do something else here
        return null;
    });

4.抛出异常

sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
    .thenThrow(RuntimeException.class);

更新

如前所述,默认行为是什么都不做,但我了解到也可以通过在创建模拟时提供 Answer 来指定替代默认行为.例如,要让默认行为改为调用真实方法:

Update

As previously mentioned, the default behavior is to do nothing, but I learned it's also possible to specify an alternate default behavior by providing an Answer when creating the mock. For example, to have the default behavior call the real method instead:

MockedStatic <MySample> sampleMock = Mockito.mockStatic( MySample.class, Mockito.CALLS_REAL_METHODS );

但要注意 - 正如 Marc 在这个答案中所指出的,即使您覆盖默认行为!这可能会在未来修复;请参阅 Marc 的回答以获得一些好的参考

But beware - as noted by Marc in this answer, the real method will still be called even if you override the default behavior! This may be fixed in the future; see Marc's answer for some good references

这篇关于是否可以使用 Mockito 模拟静态和无效的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆