retrofit-mock 無(wú)入侵式mock框架

導(dǎo)航

1、retrofit-mock用法
2、retrofit-mock編寫思路(aop)
3 、retrofit-mock的動(dòng)態(tài)代理及注解
4、aspect 原理講解與注解語(yǔ)法

1、retrofit-mock框架編寫背景需求

項(xiàng)目采用的是MVPArms框架,用的dragger方式注入,retrofiit已經(jīng)封裝在底層了,就是給上層提供服務(wù)的。沒有顯著的點(diǎn),來(lái)插入代碼。例如

var api = createMocker(service, retrofit) 

同樣,項(xiàng)目早期,我們很難專門預(yù)留出位置,做這樣的擴(kuò)展,如果接手項(xiàng)目或項(xiàng)目中期,可能需要修改網(wǎng)絡(luò)代碼,引入mock,為線上很容易引入潛在問(wèn)題,
此時(shí),我們核心訴求:

1、盡量不修改舊的網(wǎng)路代碼。
2、通過(guò)反射等手段來(lái)hook,但不影響正式包效率
3、mock測(cè)試代碼與生產(chǎn)代碼一致,不需要?jiǎng)訕I(yè)務(wù)代碼
2、編寫思路

最初考慮是反射來(lái)hook,但是需要有hook點(diǎn),插入代碼
mvparms很難找出這樣的點(diǎn),而且修改create()函數(shù),需要改動(dòng)代碼點(diǎn)很多。所以有沒有一種方式在create()函數(shù)攔截的方法
我們可以采用新的思路 采用AspectJ插件來(lái)進(jìn)行AOP攔截。
經(jīng)過(guò)實(shí)踐,aspect 不能攔截接口方法
我們可以攔截 create(service) 方法,在攔截方法注入代碼進(jìn)行我們需要的操作

3、RetrofitMock aop
@Aspect
public class RetrofitMock {

    private String TAG = "RetrofitMock";

    /** retrofit mock開關(guān)*/
    private static volatile boolean enabled = true;

    private static boolean isEnabled() {
        return enabled;
    }

    public static void setEnabled(boolean enabled) {
        RetrofitMock.enabled = enabled;
    }

    @Around("execution(* retrofit2.Retrofit.create(..))")
    public Object aroundJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {

//        Log.e( TAG, "我終于hook了retrofit" );
        if (!isEnabled()) {
            return joinPoint.proceed();//執(zhí)行原方法
        }

        Object[] parameterValues = joinPoint.getArgs();
        Retrofit retrofit = (Retrofit) joinPoint.getThis();
        Class service = (Class) parameterValues[0];
        Object api = joinPoint.proceed();

        return Proxy.newProxyInstance( service.getClassLoader(), new Class<?>[]{service}, new MockerHandler( retrofit, api ) );
    }
}

切點(diǎn)是(retrofit2.Retrofit.create())在切點(diǎn)方法里注入代碼,就可以實(shí)現(xiàn)不修改原有的網(wǎng)絡(luò)代碼實(shí)現(xiàn)效果。

如果使Aop失效,可以用RetrofitMock的空方法替換,又不損失效率,如下

public class RetrofitMock {
    /** retrofit mock開關(guān)*/
    private static volatile boolean enabled = true;
    private static boolean isEnabled() {
        return enabled;
    }
    public static void setEnabled(boolean enabled) {
        RetrofitMock.enabled = enabled;
    }
}

如用法示例

debugImplementation 'com.github.yinlingchaoliu:retrofit-mock:1.0.1'
releaseImplementation 'com.github.yinlingchaoliu:retrofit-mock-no-op:1.0.1'

release版有注解的空實(shí)現(xiàn),生產(chǎn)版本,引入會(huì)導(dǎo)致aop失效,又不損失效率

4、特別感謝

首先特別感謝javalong,給retrofit-mock提供了好的思路

本文代碼
https://github.com/yinlingchaoliu/retrofitMock

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容