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

如何用Mockito测试Java的Builder构造器?测试时Repository零交互报错如何解决

问题根因
  • 最核心的问题是你没有在测试代码中调用profileService.addProfile()方法,profileRepository的save方法自然从来没有被触发,所以报错提示零交互。
  • 你Mock的ProfileBuilder完全无效,业务代码调用Profile.builder()静态方法返回的是真实的Builder实例,不会用到你手动创建的Mock对象,而且Builder是无外部依赖的纯构造逻辑,完全不需要Mock,属于多余操作。
  • 潜在的参数匹配问题:业务代码中传给save的是Builder新生成的Profile实例,如果你没有重写Profile的equals方法,就算调用了save也会因为实例不匹配导致校验失败,不过你加了@Data注解,默认会重写equals和hashCode,属性一致即可匹配,暂时不会有问题。
修正后的测试代码
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.Objects;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class ProfileServiceImplTest {

    ProfileRepository profileRepository = Mockito.mock(ProfileRepository.class);
    private final ProfileServiceImpl profileService = new ProfileServiceImpl(profileRepository);

    City city = Mockito.mock(City.class);
    Country country = Mockito.mock(Country.class);
    Team team = Mockito.mock(Team.class);

    @Test
    public void addProfileTest(){
        // 构造入参
        Profile inputProfile = new Profile("25.07.1996", city, country, "imageId", team);
        // 打桩Repository的save方法返回结果
        Profile savedProfile = new Profile("25.07.1996", city, country, "imageId", team);
        when(profileRepository.save(any(Profile.class))).thenReturn(savedProfile);

        // 必须调用被测试的业务方法
        Profile result = profileService.addProfile(inputProfile);

        // 校验结果和调用逻辑
        assertNotNull(result);
        verify(profileRepository, times(1)).save(argThat(profile -> 
            Objects.equals(profile.getBirthDate(), inputProfile.getBirthDate()) &&
            profile.getCity() == inputProfile.getCity() &&
            profile.getCountry() == inputProfile.getCountry() &&
            Objects.equals(profile.getImageId(), inputProfile.getImageId()) &&
            profile.getTeam() == inputProfile.getTeam()
        ));
    }
}

如果你一定要Mock静态的builder方法(非常不推荐,会大幅提升测试复杂度),可以用Mockito的MockStatic功能实现,但该场景下Builder属于被测逻辑的一部分,直接真实调用即可,不需要Mock。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:18:01