MockIto+Spring测试抽象类中的方法

本文介绍如何在SpringBoot环境下测试抽象类中的方法。通过使用Mockito框架,对抽象类AManager及其依赖进行Mock,并利用AopTargetUtils工具类替换Spring容器中的托管类对象,确保测试的准确性和独立性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MockIto+Spring测试抽象类中的方法

使用场景:
抽象类AManager.class中的实现方法getSomeThing()的测试
由于是在SpringBoot的项目中,首先引入SpringBoot的测试注解


@RunWith(SpringRunner.class)
@SpringBootTest(classes = Bootstrap.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@DirtiesContext
public class AManagerTest{
...}

然后对getSomeThing()中的外部方法的调用和AManager类的成员变量进行Mock

//通过Mockito对抽象类进行mock
AManager aManager = Mockito.mock(AManager.class, Mockito.CALLS_REAL_METHODS);

File file = Mockito.mock(File.class);
RedisService redisServicemock = Mockito.mock(RedisService.class);
//通过反射获取到需要替换的成员变量 f--变量名
Field testField = AManager.class.getDeclaredField("f");
testField.setAccessible(true);
testField.set(aManager, file);

通过Mockito.when(…).thenReturn(true);对mock的成员变量或者类对象的方法设置返回值

Mockito.when(file.exists()).thenReturn(true);

对抽象类中对Spring容器中托管的类对象的替换

先给出AopTargetUtils这个抽象类,来自大神的博客

package com.zm_recordUser;

import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;

import java.lang.reflect.Field;

public class AopTargetUtils {

    /**
     * 获取 目标对象
     * @param proxy 代理对象
     * @return
     * @throws Exception
     */
    public static Object getTarget(Object proxy) throws Exception {
        if(!AopUtils.isAopProxy(proxy)) {
            return proxy;//不是代理对象
        }
        if(AopUtils.isJdkDynamicProxy(proxy)) {
            return getJdkDynamicProxyTargetObject(proxy);
        } else { //cglib
            return getCglibProxyTargetObject(proxy);
        }
    }

    private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
        Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
        h.setAccessible(true);
        Object dynamicAdvisedInterceptor = h.get(proxy);
        Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
        advised.setAccessible(true);
        return ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
    }


    private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
        h.setAccessible(true);
        AopProxy aopProxy = (AopProxy) h.get(proxy);
        Field advised = aopProxy.getClass().getDeclaredField("advised");
        advised.setAccessible(true);
        return ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
    }
}

具体使用

//先对Service进行Mock,使用注解的时候需要进行init,这里不做介绍
@Mock
XxService xxService
//或者
XxService xxService = Mockito.mock(XxService);

//以上是创建XxService的mock
//然后同样通过when...thenReturn 对XxService的某方法的返回值进行Mock
 Mockito.when(xxService.get()).thenReturn(true);

//最后通过工具类进行Service的替换        ReflectionTestUtils.setField(AopTargetUtils.getTarget(aManager),"xxService",xxServiceMock);

具体的原理和详细mock的内容后续再进行补充,这篇博文主要是对今天碰到的抽象类的方法的测试进行总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值