You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何编写JUnit用例覆盖Objects.nonNull判断分支?

JUnit无法覆盖Objects.nonNull判断分支的解决方案

问题代码

public List<ClassRoomListAdapterModel> getRoomListItems() {
    final List<ClassRoomListAdapterModel> classRoomListItemsList = new ArrayList<>();
    if (Objects.nonNull(classRoomListItemsList)) {
        classRoomListItemsList.addAll(classRoomListItemsList);
    }
    return classRoomListItemsList;
}

问题根源

这段代码中,classRoomListItemsList是方法内部直接实例化的ArrayList,永远不可能为null,因此Objects.nonNull(classRoomListItemsList)的判断永远为true:

  • 正常调用方法时,if分支必然执行,不存在无法覆盖的情况;
  • 若你想覆盖判断为false的场景(即变量为null的情况),现有代码结构无法实现,因为变量初始化逻辑硬编码在方法内部,无法模拟null值。
    另外,代码中classRoomListItemsList.addAll(classRoomListItemsList)存在逻辑问题:将列表自身元素添加到自身,空列表执行后还是空列表,非空列表会导致元素无限重复(甚至内存溢出),这大概率是笔误,应该是添加外部数据源的元素。

技术解决方案

方案1:重构代码,抽离列表初始化逻辑

将列表的来源改为方法参数,这样在测试时可以传入null值,从而覆盖所有分支:

// 重构后代码:通过参数传入外部列表
public List<ClassRoomListAdapterModel> getRoomListItems(List<ClassRoomListAdapterModel> sourceList) {
    final List<ClassRoomListAdapterModel> classRoomListItemsList = new ArrayList<>();
    if (Objects.nonNull(sourceList)) {
        classRoomListItemsList.addAll(sourceList);
    }
    return classRoomListItemsList;
}

对应的JUnit测试用例:

import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;

class YourClassTest {

    private final YourClass yourClass = new YourClass();

    @Test
    void getRoomListItems_whenSourceListIsNull_returnsEmptyList() {
        List<ClassRoomListAdapterModel> result = yourClass.getRoomListItems(null);
        assertTrue(result.isEmpty());
    }

    @Test
    void getRoomListItems_whenSourceListIsNotEmpty_returnsCombinedList() {
        List<ClassRoomListAdapterModel> sourceList = new ArrayList<>();
        sourceList.add(new ClassRoomListAdapterModel()); // 假设该类有默认构造

        List<ClassRoomListAdapterModel> result = yourClass.getRoomListItems(sourceList);
        assertEquals(1, result.size());
    }
}

方案2:使用PowerMock模拟方法内部的实例化(不推荐,仅作应急方案)

如果无法修改原代码,可以使用PowerMock来拦截new ArrayList<>()的调用,返回null值,从而覆盖判断为false的分支:

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(YourClass.class)
class YourClassTest {

    @Test
    void getRoomListItems_whenListIsNull_returnsNull() throws Exception {
        // 拦截ArrayList的构造,返回null
        PowerMockito.whenNew(ArrayList.class).withNoArguments().thenReturn(null);

        YourClass yourClass = new YourClass();
        List<ClassRoomListAdapterModel> result = yourClass.getRoomListItems();
        assertNull(result);
    }
}

注意:这种方式会破坏代码的封装性,且增加测试复杂度,仅在无法重构原代码时使用。

内容的提问来源于stack exchange,提问作者Vaibhav Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:40:35