是否可以使用 Mockito 模拟既静态又无效的方法?
Is it possible to mock a method that is both static and void using Mockito?
我尽量避免在这里使用 PowerMockito。我们有遗留代码,其中包含静态和无效的方法,并且有一些测试需要模拟它们。有没有办法做到这一点,或者重构遗留代码是这里唯一的方法吗?
class MySample {
public static void sampleMethod(String argument){
//do something
}
}
如果我使用通用的 MockStatic 语法,它会要求我 return 一些事情:
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
编辑:请注意,我正在寻找模拟既静态又无效的方法。
调用模拟方法时您希望发生什么?
默认行为是什么都不发生。通过调用 sampleMock.when()
,您表示您希望将默认行为更改为其他行为。 Mockito 抱怨是因为您随后没有调用 then___()
来指定应该发生什么。
我能想到您可能希望发生的一些不同的事情:
1。什么都不做
如前所述,这是默认行为,所以如果这就是您想要的,您可以只删除第二行,它应该可以工作。但是,如果你真的需要一个 when
调用(例如用于参数捕获),你可以用一个空的 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
来指定备用默认行为。例如,要让默认行为改为调用真正的方法:
MockedStatic <MySample> sampleMock = Mockito.mockStatic( MySample.class, Mockito.CALLS_REAL_METHODS );
但请注意 - 正如 Marc 在 中指出的那样,即使您覆盖了默认行为,实际方法仍将被调用!这可能会在未来得到解决;查看 Marc 的回答以获得一些好的参考
将 @RunWith(PowerMockRunner.class)
添加到您的 class header 将防止抛出上述异常类型!
我尽量避免在这里使用 PowerMockito。我们有遗留代码,其中包含静态和无效的方法,并且有一些测试需要模拟它们。有没有办法做到这一点,或者重构遗留代码是这里唯一的方法吗?
class MySample {
public static void sampleMethod(String argument){
//do something
}
}
如果我使用通用的 MockStatic 语法,它会要求我 return 一些事情:
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
编辑:请注意,我正在寻找模拟既静态又无效的方法。
调用模拟方法时您希望发生什么?
默认行为是什么都不发生。通过调用 sampleMock.when()
,您表示您希望将默认行为更改为其他行为。 Mockito 抱怨是因为您随后没有调用 then___()
来指定应该发生什么。
我能想到您可能希望发生的一些不同的事情:
1。什么都不做
如前所述,这是默认行为,所以如果这就是您想要的,您可以只删除第二行,它应该可以工作。但是,如果你真的需要一个 when
调用(例如用于参数捕获),你可以用一个空的 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
来指定备用默认行为。例如,要让默认行为改为调用真正的方法:
MockedStatic <MySample> sampleMock = Mockito.mockStatic( MySample.class, Mockito.CALLS_REAL_METHODS );
但请注意 - 正如 Marc 在
将 @RunWith(PowerMockRunner.class)
添加到您的 class header 将防止抛出上述异常类型!