我想使用Mockito(以及PowerMockito,如果需要)测试我的DAO方法,但我不知道如何做到这一点。调用静态方法(MySQLStationDAO中的MySQLDAOFactory.getConnection())的最大问题。你能帮助我吗?
我以这种方式获得连接:
public class MySQLDAOFactory extends DAOFactory {
public static Connection getConnection() throws DAOException {
Connection con = null;
try {
con = getDataSource().getConnection();
} catch (SQLException e) {
throw new DAOException(Messages.CANNOT_OBTAIN_CONNECTION, e);
}
return con;
}
这是一个DAO方法:
public class MySQLStationDAO implements StationDAO {
@Override
public List<Station> getAllStations() throws DAOException {
List<Station> stations = new ArrayList<>();
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
con = MySQLDAOFactory.getConnection();
stmt = con.createStatement();
rs = stmt.executeQuery(MySQLQueries.SQL_GET_ALL_STATIONS);
while (rs.next()) {
stations.add(extractStation(rs));
}
} catch (SQLException e) {
throw new DAOException(Messages.CANNOT_OBTAIN_ALL_STATIONS, e);
} finally {
MySQLDAOFactory.close(con, stmt, rs);
}
return stations;
}
答案 0 :(得分:0)
JUnit:在班级使用@RunWith(PowerMockRunner.class)
。
TestNG:让您的测试类扩展PowerMockTestCase
。
在课程级别使用@PrepareForTest(MySQLDAOFactory.class)
,以指示PowerMock准备MySQLDAOFactory
课程进行测试。
请使用PowerMockito.mockStatic(MySQLDAOFactory.class)
模拟MySQLDAOFactory
类的所有方法。
也可以使用partial mocking:
PowerMockito.stub(PowerMockito.method(MySQLDAOFactory.class, "getConnection")).toReturn(Mockito.mock(Connection.class));
使用类似的东西来存根getConnection()
:
Connection mockConnection = Mockito.mock(Connection.class);
Mockito.when(MySQLDAOFactory.getConnection()).thenReturn(mockConnection);
在getAllStations()
的实例上执行MySQLStationDAO
,因为您正在测试MySQLStationDAO
类。
如果您想验证是否已调用getConnection()
方法,请使用类似的内容:
PowerMockito.verifyStatic();
MySQLDAOFactory.getConnection();
但是,请阅读Mockito.verify(T) javadoc,了解建议存根或验证调用的原因,而不是两者。
一般情况下,您可以咨询Mockito docs和PowerMockito docs以获取更多信息。
使用JUnit 4.11,Mockito 1.9.5和PowerMock(PowerMockito)1.5.6创建的完整示例(请注意版本,因为存在许多兼容性问题):
@RunWith(PowerMockRunner.class)
@PrepareForTest(MySQLDAOFactory.class)
public class MySQLDAOFactoryTest {
private StationDAO stationDAO;
@Mock
private Connection mockConnection;
@Mock
private Statement mockStatement;
@Mock
private ResultSet mockResultSet;
@Before
public void setUp() {
stationDAO = new MySQLStationDAO();
}
@Test
public void testGetAllStations_StatementCreated() throws DAOException, SQLException {
// given
PowerMockito.mockStatic(MySQLDAOFactory.class);
Mockito.when(MySQLDAOFactory.getConnection()).thenReturn(mockConnection);
Mockito.when(mockConnection.createStatement()).thenReturn(mockStatement);
Mockito.when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet);
// when
stationDAO.getAllStations();
// then
Mockito.verify(mockConnection).createStatement();
}
}
下一步是什么?检查是否已使用预期参数调用executeQuery()
方法?测试SQLException
的处理方式?这些是单元测试的合理方案,但是集成测试呢?为此,我建议DBUnit。它将测试数据库置于测试运行之间的已知状态,并允许根据预期的XML数据集验证返回的结果。