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

如何测试依赖其他服务的Spring服务?JUnit5遇栈溢出

解决单元测试中的StackOverflowError问题

问题根源

从错误栈可以明确,栈溢出是因为User和Kelompok实体类的toString()方法发生循环递归调用:User.toString()中引用了Kelompok对象,而Kelompok.toString()又反过来引用了User对象,无限循环调用最终耗尽栈内存抛出错误。

解决方案

1. 修改实体类的toString方法

调整User和Kelompok的toString()实现,避免互相引用整个对象,只保留对方的基础属性(比如ID):

  • Kelompok类的toString修改示例:
@Override
public String toString() {
    return "Kelompok{" +
            "id=" + id +
            ", nik='" + nik + '\'' +
            // 仅引用User的ID,而非整个User对象
            ", userId=" + (user != null ? user.getId() : null) +
            '}';
}
  • User类的toString修改示例:
@Override
public String toString() {
    return "User{" +
            "id=" + id +
            // 若User关联Kelompok集合,仅保留ID列表或直接移除该属性
            ", kelompokIds=" + (kelompoks != null ? kelompoks.stream().map(Kelompok::getId).collect(Collectors.toList()) : null) +
            '}';
}

2. 优化测试类(可选,提升测试效率)

当前测试使用@SpringBootTest加载完整Spring上下文,可改用更轻量的Mockito扩展,无需加载完整Spring环境:

@ExtendWith(MockitoExtension.class)
public class KelompokServiceTest {
    private final EasyRandom EASY_RANDOM = new EasyRandom();
    private KelompokDTO kelompokDTO;

    // 注入被测试对象,自动装配mock依赖
    @InjectMocks
    KelompokService kelompokService;
    // 模拟UserService依赖
    @Mock
    private UserService userService;
    // 模拟KelompokRepository依赖
    @Mock
    private KelompokRepository kelompokRepository;

    @BeforeEach
    void setUp() {
        kelompokDTO = EASY_RANDOM.nextObject(KelompokDTO.class);
    }

    @Test
    void testSave_Success() {
        User user = EASY_RANDOM.nextObject(User.class);
        when(userService.findById(kelompokDTO.getIdUser())).thenReturn(user);

        Kelompok expectedKelompok = new Kelompok();
        expectedKelompok.setUser(user);
        expectedKelompok.setNik(kelompokDTO.getNik());
        when(kelompokRepository.save(any(Kelompok.class))).thenReturn(expectedKelompok);

        Kelompok result = kelompokService.save(kelompokDTO);

        assertEquals(expectedKelompok.getNik(), result.getNik());
        assertEquals(expectedKelompok.getUser().getId(), result.getUser().getId());
    }
}

该修改让测试启动更快,也更符合单元测试“隔离依赖”的核心原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:05:13