如何为带默认方法的泛型接口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
相关产品推荐
相关产品推荐

