【Java单元测试】实习项目实际问题5--函数内部构造局部对象

问题简单描述

FordAmbientLightManager 类中setAmbL_ALM_Set()函数,函数中进行了new AmbientLightSettingReq()的操作。
也就是:测试类的函数中构造了局部的对象,无法直接获取到该局部对象,Mockito从3.5.0版本开始支持模拟构造函数,通过Mockito.mockConstruction()接口实现。

具体情况

  1. 被测试类Java代码
public class FordAmbientLightManager extends FordCommonManager {

    private static final String TAG = "FordAmbientLightManager";
    private static FordAmbientLightManager manager;
    private AmbientLightSettingRsp ambientLightSettingRsp;
    private List<IAmbientLightChange> mIAmbientLightChangeListeners;

    public static synchronized FordAmbientLightManager getInstance(Context context) {
        if (null == manager) {
            manager = new FordAmbientLightManager(context);
        }
        return manager;
    }

    public FordAmbientLightManager(Context context) {
        super(context, APPID_ID_1021);
        mIAmbientLightChangeListeners = new ArrayList<>();
        addIResponseCallbackListener(mCallback);
        addISynchronizationInterfaceListener(mISynchronizationInterface);
    }

    //该函数内部构造了局部对象,在测试时无法直接获得这个对象
    public void setAmbL_ALM_Set(int ambL_ALM_Set) {
        AmbientLightSettingReq ambientLightSettingReq = new AmbientLightSettingReq();
        ambientLightSettingReq.setAmbL_ALM_Set(ambL_ALM_Set);
        Log.d(TAG, "setAmbL_ALM_Set:ambientLightSettingReq= " + ambientLightSettingReq.toString());
        sendRequestNoRsp(ambientLightSettingReq);
    }
}
  1. 问题具体分析
    测试类的函数中构造了局部的对象,无法直接获取到该局部对象,Mockito从3.5.0版本开始支持模拟构造函数,通过Mockito.mockConstruction()接口实现。
  2. 具体测试代码
    class FordAmbientLightManagerUT extends BaseUnitTest {


    private FordAmbientLightManager fordAmbientLightManager;
    private Context context;
    private AutoCloseable closeable;

    @BeforeAll
    public static void beforeAll() {
        mockStatic(Log.class);
        mockStatic(Car.class);
    }

    @BeforeEach
    public void beforeEach() {
        closeable = MockitoAnnotations.openMocks(this);
        Context context = Mockito.mock(Context.class);
        Mockito.when(context.getApplicationContext()).thenReturn(context);
        fordAmbientLightManager = FordAmbientLightManager.getInstance(context);
    }

    @AfterEach
    public void afterEach() throws IllegalAccessException, NoSuchFieldException {
        try {
            closeable.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Class c = fordAmbientLightManager.getClass();
        Field manager = c.getDeclaredField("manager");
        manager.setAccessible(true);
        manager.set(fordAmbientLightManager, null);

    }

    @Test
    public void testSetAmbL_IP_Color_Value() throws NoSuchFieldException, IllegalAccessException {
        //prepare
        //进行construct处理,可以理解为一个列表吧,里面都是我们想得到的mock的对象
        MockedConstruction<AmbientLightSettingReq> AmbientLightSettingReq = Mockito.mockConstruction(AmbientLightSettingReq.class);
        //invoke
        fordAmbientLightManager.setAmbL_IP_Color_Value(1);
        //verify
        //因为consruct后得到的A...Req类似列表,所以get(0)得到的就是我们想要的mock的局部变量,对此mock的局部变量再执行断言
        Mockito.verify(AmbientLightSettingReq.constructed().get(0)).setAmbL_IP_Color_Value(1);
        //construct使用结束后一定要记得关闭,否则会报错
        AmbientLightSettingReq.close();
    }
}

存在问题

  1. 只是知道遇到局部变量需要使用construct对应的语法,处理流程也会,但是不是很了解其中的原理,其实讲解过当时听明白了但是现在给忘记了 T T

技术细节

1.CONSTRUCT
技术代码
(有空手敲下,,,)

小结

1.局部对象的处理,要用到construct

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值