【Java单元测试】实习项目实际问题3--被测试类是单例模式

问题简单描述

被测试类如果是单例模式,在每次test结束后需要格外注意处理

具体情况

  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);
    }
}
  1. 问题具体分析
    因为是单例模式,所以如果测试的时候不在每一次test结束之后都对test函数中对原Java类中值作出的改变清空,会影响所有测试用例,即需要在afterEach中对具体进行处理
  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);
        //对得到的mock对象进行插桩(也就是模拟其行为)以便后续使用
        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);
        }
        //在每个test结束后都对单例进行一次初始化
        Class c = fordAmbientLightManager.getClass();
        Field manager = c.getDeclaredField("manager");
        manager.setAccessible(true);
        manager.set(fordAmbientLightManager, null);
    }
}

存在问题

技术细节

  1. 单例模式在afterEach里处理单例
  2. mock插桩的使用

小结

  1. 一开始没有考虑到是单例模式,所有测试函数写完之后一运行只有第一个过了后面全红,很崩溃,后来发现是单例模式,在每个test结束之后都要重新处理一下,体现在代码里就是在afterEach函数中对单例进行清空,这是Junit5的特性决定的,在每次test结束后都会执行一次afterEach,此时不能使用afterall,afterAll是在所有都结束之后才执行,一般和beforeAll成对出现,并且一般都是处理静态相关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值