前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用PowerMockito如何阻止静态代码块的运行

使用PowerMockito如何阻止静态代码块的运行

原创
作者头像
半月无霜
发布2024-07-17 09:29:43
1450
发布2024-07-17 09:29:43
举报
文章被收录于专栏:半月无霜

使用PowerMockito如何阻止静态代码块的运行

一、前言

在我进行单元测试mock静态类的时候,突然出现了这个异常

我就很懵逼啊,无奈只能一步一步的进去查找问题

结果发现问题出现在静态类当中,那是肯定的,我是mock了这个使用到静态方法的地方才报错的

二、简易代码复现

首先,是我们的静态类

代码语言:javascript
复制
package com.banmoon.utils;
​
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.banmoon.service.PowerMockitoService;
​
public final class PowerMockitoUtil {
​
    static {
        PowerMockitoService bean = SpringUtil.getBean(PowerMockitoService.class);
        bean.finalMethod();
    }
​
    public static String staticFinalMethod() {
        return RandomUtil.randomString(10);
    }
​
}

再然后,是我们需要单测的方法,这个方法正好使用了这个静态方法

代码语言:javascript
复制
package com.banmoon.service.impl;
​
import com.banmoon.service.PowerMockitoService;
import com.banmoon.utils.PowerMockitoUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
​
@Slf4j
@Service
@RequiredArgsConstructor
public class PowerMockitoServiceImpl implements PowerMockitoService {
​
    @Override
    public String execludeStaticCode() {
        String str = PowerMockitoUtil.staticFinalMethod();
        return "结果:" + str;
    }
​
}

那么我们的单测方法

代码语言:javascript
复制
package com.banmoon.powerMockitoTest;
​
import com.banmoon.service.impl.PowerMockitoServiceImpl;
import com.banmoon.utils.PowerMockitoUtil;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
​
import static org.powermock.api.mockito.PowerMockito.when;
​
/**
 * @author banmoon
 * @date 2024/07/16 20:20:46
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(PowerMockitoUtil.class)
public class ExcludeStaticCodeTest {
​
    @InjectMocks
    private PowerMockitoServiceImpl powerMockitoService;
​
    @Test
    public void testExecludeStaticCode() {
        // 设置参数
        PowerMockito.mockStatic(PowerMockitoUtil.class);
        when(PowerMockitoUtil.staticFinalMethod()).thenReturn("mock");
​
        // 运行测试
        String string = powerMockitoService.execludeStaticCode();
​
        // 验证结果
        Assert.assertEquals("结果:mock", string);
    }
​
}

一执行单测,就报错了,报错截图如下

三、修复

我们在单测的时候, 不可能为了单测去修改除测试方法以外的代码逻辑的

比如这次的PowerMockitoUtil.java,当中的静态代码块虽然只是我的模拟。

但它在正常的容器下运行就是正常且必须的

那么我们就得想办法绕过去了,正好PowerMockito提供了一个注解,可以帮助我们取消静态代码块的执行

@SuppressStaticInitializationFor,使用如下

代码语言:javascript
复制
package com.banmoon.powerMockitoTest;
​
import com.banmoon.service.impl.PowerMockitoServiceImpl;
import com.banmoon.utils.PowerMockitoUtil;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;
​
import static org.mockito.Mockito.when;
​
/**
 * @author banmoon
 * @date 2024/07/16 20:20:46
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(PowerMockitoUtil.class)
@SuppressStaticInitializationFor("com.banmoon.utils.PowerMockitoUtil")
public class ExcludeStaticCodeTest {
​
    @InjectMocks
    private PowerMockitoServiceImpl powerMockitoServiceImplUnderTest;
​
    @Test
    public void testExecludeStaticCode() {
        // 设置参数
        PowerMockito.mockStatic(PowerMockitoUtil.class);
        when(PowerMockitoUtil.staticFinalMethod()).thenAnswer(invocation -> "mock");
​
        // 运行测试
        String string = powerMockitoServiceImplUnderTest.execludeStaticCode();
​
        // 验证结果
        Assert.assertEquals("结果:mock", string);
    }
​
}

四、最后

在进行code运行的时候,又出现了一个报错

代码语言:javascript
复制
org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class java.lang.Class

后面再检查一下是什么问题

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用PowerMockito如何阻止静态代码块的运行
    • 一、前言
      • 二、简易代码复现
        • 三、修复
          • 四、最后
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档