Mockito -- 如何Mock Util类中的static 方法?

大家好,我是神韵,是一个技术&生活博主。出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己。二是希望我的文章可以帮到大家。欢迎来点赞打卡,你们的行动将是我无限的动力。
本篇主题是:Mockito -- 如何Mock Util类中的static 方法?

比如要Mock下面的DateUtils类中static-convertLocalDateTimeToStr方法,下面只是一个例子,真实场景中可能非常复杂的xxUtils

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtils {

    public static String convertLocalDateTimeToStr(LocalDateTime localDateTime) {
        // 比较复杂的业务 假设~

        // 转化
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return localDateTime.format(dateFormatter);
    }
}

1、引入依赖

注意要引入mockito-inline依赖代替mockito-core,不然会报错

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.1</version>
  </parent>

  <dependencies>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-inline</artifactId>
    </dependency>
  </dependencies>

2、编写测试类

@RunWith(MockitoJUnitRunner.class)
public class DateUtilsTest {

    @Test
    public void testConvertLocalDateTimeToStr() {
        String expectResult = "mock static method successful";
        MockedStatic<DateUtils> dateUtilsMockedStatic = Mockito.mockStatic(DateUtils.class);
        dateUtilsMockedStatic.when(() -> DateUtils.convertLocalDateTimeToStr(Mockito.any())).thenReturn(expectResult);
        
        String result = DateUtils.convertLocalDateTimeToStr(LocalDateTime.now());
        Assert.assertEquals(expectResult, result);
    }
}

用Mockito.mockStatic对DateUtils进行mock之后,用when模拟相应行为就可以。例子中mock之后使之响应"mock static method successful"内容,然后用Assert对比mock是否成功。

3、如果要多个测试类中使用,需要close掉mock static,不然会报只能在当前线程使用

dateUtilsMockedStatic.close();

@RunWith(MockitoJUnitRunner.class)
public class DateUtilsTest {

    @Test
    public void testConvertLocalDateTimeToStr() {
        String expectResult = "mock static method successful";
        MockedStatic<DateUtils> dateUtilsMockedStatic = Mockito.mockStatic(DateUtils.class);
        dateUtilsMockedStatic.when(() -> DateUtils.convertLocalDateTimeToStr(Mockito.any())).thenReturn(expectResult);

        String result = DateUtils.convertLocalDateTimeToStr(LocalDateTime.now());
        Assert.assertEquals(expectResult, result);
        dateUtilsMockedStatic.close();
    }

    @Test
    public void testConvertLocalDateTimeToStr2() {
        String expectResult = "mock static method successful";
        MockedStatic<DateUtils> dateUtilsMockedStatic = Mockito.mockStatic(DateUtils.class);
        dateUtilsMockedStatic.when(() -> DateUtils.convertLocalDateTimeToStr(Mockito.any())).thenReturn(expectResult);

        String result = DateUtils.convertLocalDateTimeToStr(LocalDateTime.now());
        Assert.assertEquals(expectResult, result);
        dateUtilsMockedStatic.close();
    }
}

注意

1、要引入mockito-inline依赖代替mockito-core,不然会报下面错误

org.mockito.exceptions.base.MockitoException: 
The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks

Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.

2、多个测试类没有close当前mockStatic时,会报下面错误

org.mockito.exceptions.base.MockitoException: 
For pers.xue.skills.util.DateUtils, static mocking is already registered in the current thread

To create a new mock, the existing static mock registration must be deregistered

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mockito 默认不支持模拟静态方法,但是可以使用第三方库 PowerMockito 来模拟静态方法。下面是一个例子: 假设有一个类 `StringUtil`,其中有一个静态方法 `isEmpty`,我们需要对其进行模拟: ``` public class StringUtil { public static boolean isEmpty(String str) { return str == null || str.isEmpty(); } } ``` 使用 PowerMockito 可以这样模拟: ``` @RunWith(PowerMockRunner.class) @PrepareForTest(StringUtil.class) public class StringUtilTest { @Test public void testIsEmpty() { PowerMockito.mockStatic(StringUtil.class); // mock 静态方法 Mockito.when(StringUtil.isEmpty(Mockito.anyString())).thenReturn(true); // 模拟静态方法的行为 Assert.assertTrue(StringUtil.isEmpty(null)); Assert.assertTrue(StringUtil.isEmpty("")); Assert.assertTrue(StringUtil.isEmpty(" ")); Assert.assertFalse(StringUtil.isEmpty("abc")); } } ``` 在上面的代码中,我们使用了 `@RunWith(PowerMockRunner.class)` 和 `@PrepareForTest(StringUtil.class)` 来启用 PowerMockito静态方法模拟功能,并指定要模拟的类。然后使用 `PowerMockito.mockStatic(StringUtil.class)` 来 mock 静态方法,最后使用 `Mockito.when` 来模拟静态方法的行为。 需要注意的是,使用 PowerMockito 进行静态方法模拟需要添加相应的依赖,否则会报 NoClassDefFoundError 错误。例如,使用 Maven 的项目需要添加以下依赖: ``` <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-core</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值