Spring Boot Junit动态代理实现Mock方法

说到Spring Boot 单元测试主要有两个主流集成分别是Mockito,Junit,这个各有特点,在实际开发中,我想要的测试框架应该是这个框架集成者。要有Junit能够运行某一个单元用例,完整的项目环境,又需要Mockito能对某一个依赖进行注入,指定返回值内容。可惜实际中这两个框架根本不能同时运行的。突然想到可以通过AOP的环绕通知来实现Mock注入功能,覆盖某一个方法返回值。 现在有一个Feign接口AService,实际情况我们环境根本就没有这个服务,调用这个方法一定会报错的。通过代理技术的环绕通知覆盖返回值,能让方法正常调用。具体代码实现如下

Feign 代码

kotlin 复制代码
@FeignClient(name = "application-a")
public interface AFeignService {

    @RequestMapping("/url/path/get")
    Result<Object> get();
}

测试用例

less 复制代码
@SpringBootTest
@Slf4j
class AFeignServiceTest {

    @Autowired
    private AFeignService aFeignService;

    @Test
    void get() {
        Result<Object> result = aFeignService.get();
        log.info(JSONObject.toJSONString(result));
    }
}

执行测试用例,一定会出错,缺少代理方法 在test中添加代理配置类

less 复制代码
@Aspect
@Slf4j
public class AspConfig {

    @Pointcut("execution(* com..AFeignService.get(..))")
    public void pointcue(){

    }

    @Around("pointcue()")
    public Object overrideReturnValue(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("AspConfig.overrideReturnValue execute .................");
        //joinPoint.proceed();  不调用原来方法
        ErpReturnDTO dto = new ErpReturnDTO();
        dto.setStatus(200);
        dto.setSuccess(true);
        dto.setMessage("success");
        dto.setData(new ArrayList<>());
        Result<ErpReturnDTO> result = Result.succeed(dto);
        return result;
    }

}

添加切面配置类,这是用于测试用途的代码,不能写在src/代码上,而是使用ImportBeanDefinitionRegistrar,在测试中引用进来。 ImportBeanDefinitionRegistrar: 是Spring提供接口,运行开发者添加自定义添加自己的配置类,Spring Boot组件扩展就是通过这个接口来实现的。

java 复制代码
public class TestAopImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(AspConfig.class);
        GenericBeanDefinition definition = (GenericBeanDefinition) definitionBuilder.getRawBeanDefinition();
        registry.registerBeanDefinition(AspConfig.class.getName(), definition);
    }

}

在原来的单元测试引入代理配置就可以了

less 复制代码
@SpringBootTest
@Slf4j
@Import(TestAopImportBeanDefinitionRegistrar.class)
class AFeignServiceTest

再次运行测试用例,没有异常,并且返回对象成功打印出来

ruby 复制代码
{"code":0,"data":{"data":[],"message":"success","status":200,"subMessage":"success","success":true},"msg":"操作成功","success":true}

有这个代理配置,就可以在平常的开发中,对单元测试中的依赖进行代理覆盖返回值,达到Mock某个方法的返回值效果了。

相关推荐
顽疲19 分钟前
java springboot vue 养老系统源码详解:请假 care_leave 销假与床位停费日扣实践
java·vue.js·spring boot
Java_AI工程师1 小时前
Spring4 / SpringBoot1.x 老项目想接入 AI?不用升级框架!3 套无痛落地方案
java·人工智能·spring boot
VimorphTech1 小时前
Java 文件缓存实战:如何避免读到未下载完成的视频?
java·spring boot
十年Java程序媛3 小时前
JVM 内存区域与对象内存布局|new 对象底层流程,对象头 MarkWord 详解
java·jvm·spring boot
linyb极客之路3 小时前
Spring Boot 2升3太痛苦?用OpenRewrite批量搞定,少走90%弯路!
spring boot
171320330计算机毕设编程3 小时前
计算机毕业设计 基于springboot+vue的在线观鸟视频播放网站 LW PPT
java·大数据·vue.js·spring boot·算法·课程设计
星辰云-8 小时前
# 基于Spring Boot的德州特产扒鸡商城系统(毕设|源码|论文|演示视频)
spring boot·后端·课程设计
星辰云-8 小时前
基于Spring Boot的旅游景点票务系统的设计与实现(毕设项目,附完整源码)
spring boot·后端·课程设计
十年Java程序媛9 小时前
JVM 基础与 GC 垃圾回收详解|可达性分析、分代模型、垃圾收集器、STW
java·开发语言·jvm·spring boot·后端·面试
她的男孩10 小时前
JAR 全对仍 checksum mismatch:Forge Admin 把 Flyway 从 filesystem 改成 classpath
java·数据库·spring boot