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

如何为Try-Catch块编写JUnit测试以覆盖异常分支?

JUnit测试覆盖Catch块问题排查与修正

我正在为一段包含Try-Catch的数据库健康检查代码编写JUnit测试,已经实现了Try块的覆盖率,但始终无法覆盖Catch块。

待测试代码

public boolean testDb() {
    boolean dbHealth = true;
    try {
        Session session = sessionFactory.getCurrentSession();
        SQLQuery sqlQuery = session.createSQLQuery("SELECT empId from employee");
        sqlQuery.executeUpdate();
    } catch (Exception e) {
        dbHealth = false;
        LOG.error(e);
    }
    return dbHealth;
}

现有测试代码(未生效)

@Test
public void testDb_throwException() {
  SessionFactory sessionFactory = mock(SessionFactory.class);
  Session session= mock(Session.class);
  Query query = mock(Query.class);
  when(sessionFactory.getCurrentSession()).thenReturn(session);
  when(sessionFactory.openSession()).thenReturn(session);
  when(mockSession.createSQLQuery(Mockito.anyString())).thenReturn(query);
  when(query.executeUpdate()).thenThrow(new RuntimeException("sql exception"));
  boolean res= baseDaoImpl.testDatabaseHealth();
  Assert.assertTrue(res);
}

问题排查与修正

现有测试存在三个关键问题导致无法进入Catch块:

  • 引用未定义的mockSession对象,应使用已mock的session变量
  • 断言逻辑错误:Catch块返回false,但测试中误用Assert.assertTrue(res)
  • 未将mock的sessionFactory注入到baseDaoImpl实例,导致测试实际使用非mock对象

修正后的测试代码

@Test
public void testDb_throwException() {
    // 创建mock对象
    SessionFactory sessionFactory = mock(SessionFactory.class);
    Session session = mock(Session.class);
    SQLQuery sqlQuery = mock(SQLQuery.class); // 匹配原代码的SQLQuery类型

    // 将mock注入目标对象(根据实际注入方式调整,这里假设用setter)
    baseDaoImpl.setSessionFactory(sessionFactory);

    // 定义mock行为
    when(sessionFactory.getCurrentSession()).thenReturn(session);
    when(session.createSQLQuery(Mockito.anyString())).thenReturn(sqlQuery);
    when(sqlQuery.executeUpdate()).thenThrow(new RuntimeException("sql exception"));

    // 执行测试并断言
    boolean res = baseDaoImpl.testDb();
    Assert.assertFalse(res);
}

额外注意事项

  • 保持mock对象类型与原代码一致:原方法使用SQLQuery,不要用父类Query,否则类型不匹配会导致mock失效
  • 确认注入方式:如果baseDaoImpl的sessionFactory是构造函数注入,需在实例化时传入mock对象;字段注入可使用@InjectMocks注解自动注入
  • 异常选择:抛出RuntimeException即可触发Catch块,也可根据需求抛出更具体的异常如SQLException

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:20:36