我试图为下面的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;
}
这就是我尝试覆盖捕获块的方法,但仍然覆盖了“尝试”块而不是“捕获”块
@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);
}
这里有一些事情发生。
首先,您在这个测试中创建的所有模拟都没有被注入到被测试的服务中,所以它们没有做任何事情。
其次,您从名为“session”的sessionfactory返回一个模拟,但是您在名为“mockSession”的模拟上的定义行为,请参见这两行:
when(sessionFactory.openSession()).thenReturn(session);
when(mockSession.createSQLQuery(Mockito.anyString())).thenReturn(query);
第三,我怀疑您的测试类已经有了一个已配置的< code>baseDaoImpl,其中注入了mocks,否则它会在几个地方抛出npe。您要做的是在这些模拟上进行配置。如果您要在其他测试中使用reset返回其他模拟实例,那么您需要在全局SessionFactory mock上使用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());
}
}