如何使用Mockito测试DAO?

时间:2019-07-01 07:23:02

标签: java unit-testing junit mocking mockito

我是单元测试的新手,我正在尝试为我的DAO编写一些测试。我在这里遵循了一些教程/答案,但是其中大多数不适用于我的DAO。

运行测试时收到此警告 org.mockito.exceptions.verification.WantedButNotInvoked: 想要但不被调用: mockConn.prepareStatement();

怎么了?

private ApprovalConditionDAO approvalConditionDAO;
@Mock
DataSource mockDataSource;
@Mock
Connection mockConn;
@Mock
PreparedStatement mockPreparedStmnt;
@Mock
CallableStatement cs;
@Mock
ResultSet mockResultSet;

@Before
public void setUp() throws SQLException {
    approvalConditionDAO = new ApprovalConditionDAO();
    when(mockDataSource.getConnection()).thenReturn(mockConn);
    when(mockDataSource.getConnection(anyString(),
                                      anyString())).thenReturn(mockConn);
    when(mockConn.prepareStatement(anyString(),
                                   anyInt())).thenReturn(mockPreparedStmnt);
    doNothing().when(mockConn).commit();
    doNothing().when(mockPreparedStmnt).setString(anyInt(), anyString());
    when(mockPreparedStmnt.execute()).thenReturn(Boolean.TRUE);
    when(mockPreparedStmnt.getGeneratedKeys()).thenReturn(mockResultSet);
    when(mockResultSet.next()).thenReturn(Boolean.TRUE, Boolean.FALSE);
}

@Test
public void testCreateWithNoExceptions() throws SQLException {    
   ArrayList<ApprovalConditionBean> actualValues = approvalConditionDAO.getAllApprovalCondition();

    //verify and assert
    verify(mockConn, times(1)).prepareStatement(anyString());
    verify(mockPreparedStmnt, times(1)).execute();
    verify(mockConn, times(1)).commit();
    verify(mockResultSet, times(2)).next();
    verify(mockResultSet, times(1)).getString("ID");
    verify(mockResultSet, times(1)).getString("EIT_CODE");
    verify(mockResultSet, times(1)).getString("FRIST_KEY_TYPE");
    verify(mockResultSet, times(1)).getString("FRIST_KEY_VALUE");
    verify(mockResultSet, times(1)).getString("FRIST_EIT_SEGMENT");
    verify(mockResultSet, times(1)).getString("OPERATION");
    verify(mockResultSet, times(1)).getString("SECOND_KEY_TYPE");
    verify(mockResultSet, times(1)).getString("SECOND_KEY_VALUE");
    verify(mockResultSet, times(1)).getString("SECOND_EIT_SEGMENT");
    verify(mockResultSet, times(1)).getString("APPROVAL_CODE");
}

这是我要测试的Dao。

  public class ApprovalConditionDAO extends AppsproConnection {
Connection connection;
PreparedStatement ps;
CallableStatement cs;
ResultSet rs;
RestHelper rh = new RestHelper();


public ArrayList<ApprovalConditionBean> getAllApprovalCondition() {

 ArrayList<ApprovalConditionBean> approvalConditionList =
     new ArrayList<ApprovalConditionBean>();
 try {
     connection = AppsproConnection.getConnection();
     String query =
         "SELECT * FROM "+" "+getSchema_Name()+".XXX_APPROVAL_CONDITION";
     ps = connection.prepareStatement(query);
     rs = ps.executeQuery();
     while (rs.next()) {
         ApprovalConditionBean approvalConditionBean = new ApprovalConditionBean();
         approvalConditionBean.setId(rs.getString("ID"));
         approvalConditionBean.setEitCode(rs.getString("EIT_CODE"));
         approvalConditionBean.setFirstKeyType(rs.getString("FRIST_KEY_TYPE"));
         approvalConditionBean.setFirstKeyValue(rs.getString("FRIST_KEY_VALUE"));
         approvalConditionBean.setFirstEitSegment(rs.getString("FRIST_EIT_SEGMENT"));
         approvalConditionBean.setOperation(rs.getString("OPERATION"));
         approvalConditionBean.setSecondKeyType(rs.getString("SECOND_KEY_TYPE"));
         approvalConditionBean.setSecondKeyValue(rs.getString("SECOND_KEY_VALUE"));
         approvalConditionBean.setSecondEitSegment(rs.getString("SECOND_EIT_SEGMENT"));
         approvalConditionBean.setApprovalCode(rs.getString("APPROVAL_CODE"));


         approvalConditionList.add(approvalConditionBean);

     }

 } catch (Exception e) {
     //("Error: ");
     e.printStackTrace();
 } finally {
     closeResources(connection, ps, rs);
 }
 return approvalConditionList;

}

这是我的AppsproConnection Calss

     public static Connection getConnection(boolean commit) {
    if (CommonConfigReader.getValue("CONNECTION_TYPE").equalsIgnoreCase("JDBC")) {
        return getJDBCConnection(commit);
    } else {
        return getDSConnection(commit);
    }
}

public static Connection getConnection() {
    if (CommonConfigReader.getValue("CONNECTION_TYPE").equalsIgnoreCase("JDBC")) {
        return getJDBCConnection();
    } else {
        return getDSConnection();
    }
}

1 个答案:

答案 0 :(得分:1)

您没有从测试方法中调用要测试的方法。
您没有事件可以这样做。

class TestClass {
    private MyDao underTest;

    @Before
    public void setUp() throws SQLException {
        underTest = new MyDao();
        // mocking things...
    }
}

使用该测试对象,您必须从测试方法中调用您实际要测试的方法。

@Test
public void testCreateWithNoExceptions() throws SQLException {
    // ...

    ArrayList<ApprovalConditionBean> actualValues = underTest.getAllApprovalCondition();

    // assertions
}

如果无法操纵如何从静态类获取连接,则可以重构您的方法以从同一类的另一个方法获取连接。

public ArrayList<ApprovalConditionBean> getAllApprovalCondition() {
    // ...
    connection = getConnection();
    // ...
}

Connection getConnection() {
    return AppsproConnection.getConnection();
}

如果使用这种方法,则可以实例化测试对象,从而可以管理返回哪种类型的连接以进行测试。

@Before
public void setUp() throws SQLException {
    when(mockConn.prepareStatement(anyString(), anyInt())).thenReturn(mockPreparedStmnt);
    doNothing().when(mockConn).commit();
    doNothing().when(mockPreparedStmnt).setString(anyInt(), anyString());
    when(mockPreparedStmnt.execute()).thenReturn(Boolean.TRUE);
    when(mockPreparedStmnt.getGeneratedKeys()).thenReturn(mockResultSet);
    when(mockResultSet.next()).thenReturn(Boolean.TRUE, Boolean.FALSE);

    underTest = new MyDao(){
        @Override
        public Connection getConnection() {
            return mockConn;
        }
    };
}

我们正在从getConnection返回模拟的连接。从getAllApprovalCondition方法中调用此方法。在生产中,它仍通过AppsproConnection提供连接。