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

如何对包含ModelMapper调用的Service层方法进行单元测试

你的思路是合理的,这里提供两种常见的实现方案,可根据你的测试目标选择:

方案1:对ModelMapper的map方法打桩模拟映射逻辑

适合你希望在本次测试中直接验证最终返回实体的属性值的场景
因为ModelMapper的map(request, entity)是void方法,会直接修改第二个入参的属性,你可以用Mockito的Answer来模拟这个行为,补充你的测试代码如下:

@Test
void givenValidEntity_whenUpdateEntity_shouldUpdateProperties() {
    //given
    String code = "TEST";
    Entity expected = new Entity();
    expected.setName("Old");

    EntityDTO request = new EntityDTO();
    request.setName("New");

    given(repository.findByCode(code)).willReturn(expected);
    // 打桩modelMapper的map方法,模拟属性映射
    given(modelMapper.map(eq(request), any(Entity.class))).willAnswer(invocation -> {
        Entity toUpdate = invocation.getArgument(1);
        toUpdate.setName(request.getName());
        // 有其他需要映射的字段也可以在这里补充赋值逻辑
        return null;
    });
    // 打桩repository.save,返回修改后的实体
    given(repository.save(expected)).willReturn(expected);

    //when
    Entity updatedEntity = service.updateEntity(code, request);

    //then
    assertEquals(request.getName(), updatedEntity.getName());
}

方案2:用ArgumentCaptor验证调用流程(更推荐单元测试场景)

适合ModelMapper本身的映射逻辑已经有单独测试覆盖,只需要验证Service流程正确性的场景
单元测试Service的核心目标是验证流程逻辑正确,不需要耦合Mapper本身的功能测试,这时候用ArgumentCaptor更合适:
首先在测试类中声明参数捕获器:

@Captor
private ArgumentCaptor<EntityDTO> dtoCaptor;
@Captor
private ArgumentCaptor<Entity> entityCaptor;

修改测试逻辑如下:

@Test
void givenValidEntity_whenUpdateEntity_shouldUpdateProperties() {
    //given
    String code = "TEST";
    Entity existEntity = new Entity();
    existEntity.setName("Old");

    EntityDTO request = new EntityDTO();
    request.setName("New");

    given(repository.findByCode(code)).willReturn(existEntity);
    given(repository.save(any(Entity.class))).willReturn(existEntity);

    //when
    service.updateEntity(code, request);

    //then
    // 验证modelMapper被调用时传入了正确的参数
    verify(modelMapper).map(dtoCaptor.capture(), entityCaptor.capture());
    assertEquals(request, dtoCaptor.getValue());
    assertEquals(existEntity, entityCaptor.getValue());
    // 验证repository.save传入的是同一个实体
    verify(repository).save(entityCaptor.capture());
    assertEquals(existEntity, entityCaptor.getValue());
}

这个方案不需要模拟Mapper的具体映射逻辑,耦合度更低,测试稳定性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:09:01