如何为try catch块写junit ?



我正在尝试为下面的try-catch块编写junit,以提高代码的覆盖率。我已经对try块进行了测试,但是如何对catch块进行测试呢?下面是带有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;
}

这是我尝试的catch块的覆盖,但仍然是'try'块被覆盖,而不是'catch'块

@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);
}

这里有几件事。

首先,您在此测试中创建的所有mock都没有被注入到测试中的服务中,因此它们没有做任何事情。

第二,您将从名为"session"的session"返回一个模拟,但是您在名为"mockSession"的模拟上定义的行为,参见这两行:

when(sessionFactory.openSession()).thenReturn(session);
when(mockSession.createSQLQuery(Mockito.anyString())).thenReturn(query);

第三,我怀疑您的测试类已经配置了一个baseDaoImpl,并将mock注入其中,否则它将在一些地方抛出npe。您需要做的是在这些模拟上进行配置。如果您打算在其他测试中使用全局SessionFactory模拟来返回其他模拟实例,则需要对其使用reset。

这里是一个完整的测试类,我相信你的baseDaoImpl看起来像。它包含了我知道的所有导入,我不知道您使用的是哪个Session、SessionFactory或SQLQuery类。

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class BaseDaoImplTest {
@Mock // mock the session factory
SessionFactory sessionFactory;
@InjectMocks // inject the mock into the baseDao
BaseDaoImpl baseDao;
@Test
void somethingToTest() {
// define query mock to throw exception
SQLQuery sqlQuery = mock(SQLQuery.class);  // your class actually returns an SQLQuery, so you need to mock this and not the interface
when(sqlQuery.executeUpdate()).thenThrow(new RuntimeException("sql exception"));
// define session mock to return the sqlQuery mock created above
Session session = mock(Session.class);
when(session.createSQLQuery(anyString())).thenReturn(sqlQuery);
// instruct the session factory mock that's injected into your class under test to return the session created above
when(sessionFactory.getCurrentSession()).thenReturn(session);
assertFalse(baseDao.somethingToTest());
}
@Test
void somethingToTest_condensedVersion() {
// since all your want to test is that the catch block behaves properly,
// instruct the session factory mock to throw an exception
when(sessionFactory.getCurrentSession()).thenThrow(new RuntimeException());
assertFalse(baseDao.somethingToTest());
}
}

最新更新