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

如何为带默认方法的泛型接口XYZConverter编写测试用例?

如何为带默认方法的泛型接口编写测试用例?

接口定义

public interface XYZConverter <D extends DomainClass, E extends EntityClass>{
   E createFrom(D dto);
   E updateEntity(E entity, D dto);
   
   default List<E> createFromDtos(Collection<D> dtos){
       return dtos.stream().map(this::createFrom).collect(Collectors.toList());
   }
}

现有测试代码的问题

你当前的测试代码存在几个关键问题:

  • 泛型测试类未绑定具体的DomainClass/EntityClass子类,Mockito无法直接正确处理泛型接口的spy
  • 语法错误:EntityClass = getEntityClass(); 属于非法赋值,应该是变量赋值而非类名
  • Mockito.when的参数写法错误:Collection<D> domainClass不是合法的参数传递方式
  • 未正确配置Mockito来调用接口的默认方法,默认方法不会被自动执行

正确的测试实现

要测试默认方法createFromDtos,核心是让Mockito调用真实的默认方法逻辑,同时mock依赖的抽象方法createFrom的行为,示例代码如下:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

// 绑定具体的Domain和Entity子类,若没有子类可保留泛型参数并指定类型
public class XYZConverterTest {

    private XYZConverter<DomainClass, EntityClass> converter;

    @Mock
    private DomainClass mockDomain;

    @Mock
    private EntityClass mockEntity;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        // 创建接口mock实例,指定调用真实默认方法
        converter = mock(XYZConverter.class, CALLS_REAL_METHODS);
    }

    @Test
    void createFromDtos_shouldConvertAllDtos() {
        // 准备测试数据
        List<DomainClass> testDtos = List.of(mockDomain, mockDomain);

        // mock抽象方法行为:传入任意DomainClass实例返回mockEntity
        when(converter.createFrom(any(DomainClass.class))).thenReturn(mockEntity);

        // 调用待测试的默认方法
        List<EntityClass> result = converter.createFromDtos(testDtos);

        // 断言结果正确性
        assertEquals(testDtos.size(), result.size());
        assertEquals(mockEntity, result.get(0));
        assertEquals(mockEntity, result.get(1));

        // 验证createFrom被调用次数符合预期
        verify(converter, times(2)).createFrom(mockDomain);
    }
}

关键说明

  • 使用mock(XYZConverter.class, CALLS_REAL_METHODS):告诉Mockito执行默认方法的真实逻辑,抽象方法使用mock行为
  • 无需spy整个接口,mock+真实方法调用的方式更简洁
  • 验证createFrom的调用次数,确保默认方法的流处理逻辑正确执行
  • 若存在DomainClass/EntityClass的具体子类,建议替换测试类泛型参数为具体子类,避免类型擦除问题

内容的提问来源于stack exchange,提问作者MAYANK DEVRANI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:00:23