mockito如何mock 静态方法,在执行该方法时,不要执行
时间: 2025-08-12 16:00:44 浏览: 13
<think>我们正在使用Mockito来模拟静态方法,并且希望在不执行实际逻辑的情况下进行模拟。Mockito从3.4.0版本开始支持静态方法的模拟。我们需要使用Mockito的mockStatic方法,并且通过when...then...来定义模拟行为。
步骤:
1. 添加依赖:确保项目中包含Mockito-inline依赖(因为静态模拟需要mockito-inline,而不是mockito-core)。
2. 使用Mockito.mockStatic创建静态方法的模拟。
3. 使用try-with-resources(或手动关闭)来确保模拟的作用域,避免影响其他测试。
4. 使用when定义静态方法调用时的行为。
注意:在模拟静态方法时,我们不会执行实际的方法逻辑,而是返回我们指定的值或抛出指定的异常。
示例代码:
假设我们有一个类`StringUtils`,其中有一个静态方法`isNullOrEmpty(String str)`,我们想要模拟这个方法,使其在测试中不执行实际逻辑,而是返回我们指定的值。
首先,确保依赖(以Maven为例):
```xml
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.12.4</version> <!-- 请使用最新稳定版本 -->
<scope>test</scope>
</dependency>
```
然后,在测试中:
```java
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
public class StringUtilsTest {
@Test
void testStaticMethodMocking() {
// 创建静态模拟
try (MockedStatic<StringUtils> mockedStatic = Mockito.mockStatic(StringUtils.class)) {
// 模拟静态方法的行为:当传入任意字符串时,都返回true
mockedStatic.when(() -> StringUtils.isNullOrEmpty(anyString())).thenReturn(true);
// 现在调用静态方法将不会执行实际逻辑,而是返回我们模拟的值
assertTrue(StringUtils.isNullOrEmpty("Hello")); // 这里返回true,而不是实际判断
}
// 在try-with-resources块外,静态方法将恢复原始行为
}
}
```
解释:
- 我们使用`Mockito.mockStatic`来模拟`StringUtils`类,并得到一个`MockedStatic`对象。
- 使用`try-with-resources`语句来确保在测试结束后关闭模拟,这样就不会影响其他测试。
- 在`try`块内,我们使用`mockedStatic.when`来定义当调用静态方法`isNullOrEmpty`(参数为任意字符串)时,返回`true`。
- 然后我们在测试中调用该方法,它会返回模拟的值,而不是执行实际的方法体。
这样,我们就实现了在不执行实际逻辑的情况下模拟静态方法。
注意:Mockito的静态模拟目前是使用线程局部状态来实现的,因此请确保在同一个线程中执行模拟和调用。另外,静态模拟可能会影响性能,因此建议仅在必要时使用。
相关问题:
1. 如何在Mockito中模拟静态方法?
2. Mockito模拟静态方法时如何设置返回值?
3. 如何确保Mockito的静态模拟不会影响其他测试?
4. Mockito模拟静态方法需要什么依赖?
5. 除了静态方法,Mockito还能模拟哪些类型的方法?</think>### 使用Mockito模拟静态方法(不执行实际逻辑)
在Mockito 3.4.0及以上版本中,可通过`mockStatic`方法模拟静态方法,并跳过实际逻辑执行。以下是完整实现步骤:
#### 1. 添加依赖
```xml
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.11.0</version> <!-- 使用最新版本 -->
<scope>test</scope>
</dependency>
```
#### 2. 模拟静态方法(示例代码)
```java
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
class MyUtility {
public static String staticMethod() {
System.out.println("实际逻辑被执行"); // 这行不会执行
return "real-value";
}
}
public class StaticMockTest {
@Test
void testStaticMockWithoutExecution() {
// 创建静态方法的模拟作用域
try (MockedStatic<MyUtility> mockedStatic = Mockito.mockStatic(MyUtility.class)) {
// 配置模拟行为(跳过实际逻辑)
mockedStatic.when(MyUtility::staticMethod)
.thenReturn("mocked-value"); // 直接返回预设值
// 执行测试(不会触发实际逻辑)
String result = MyUtility.staticMethod();
System.out.println(result); // 输出: mocked-value
// 验证调用
mockedStatic.verify(MyUtility::staticMethod);
}
// 作用域结束后自动恢复原始静态方法
}
}
```
#### 关键说明:
1. **作用域控制**
使用`try-with-resources`确保模拟作用域结束后自动释放静态mock,避免影响其他测试[^1]。
2. **跳过实际逻辑的原理**
`thenReturn()`直接返回预设值,不会进入方法体。原始方法中的代码(如日志/计算)完全不会执行。
3. **行为配置选项**:
```java
// 返回指定值
mockedStatic.when(MyUtility::staticMethod).thenReturn("value");
// 抛出异常
mockedStatic.when(MyUtility::staticMethod).thenThrow(new RuntimeException());
// 无返回值方法
mockedStatic.when(MyUtility::voidStaticMethod).thenAnswer(invocation -> null);
```
4. **版本要求**
静态mock需Mockito 3.4.0+和`mockito-inline`依赖(替代`mockito-core`)[^2]。
#### 注意事项:
- 每个静态mock作用域需独立关闭,避免跨测试污染
- 不可模拟final类/方法(需配置`src/test/resources/mockito-extensions`文件)
- 优先考虑重构静态方法为实例方法,提高可测试性
---
阅读全文
相关推荐




















