当前位置: 首页 > 面试题库 >

如何使用Mockito测试DAO方法?

高高雅
2023-03-14
问题内容

我已经开始发现Mockito库,并且有一个我没有找到正确答案的问题。

例如,如果我的UserDAO类中有将用户保存到数据库中的此类方法:

public class UserDAO{
...
 public void create(User user) {
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet generatedKeys = null;
        try {

            connection = getConnection();
            pstmt = connection.prepareStatement(INSERT_USER,
                    PreparedStatement.RETURN_GENERATED_KEYS);
            int counter = 1;
            pstmt.setString(counter++, user.getFirstName());
            pstmt.setString(counter++, user.getLastName());
            pstmt.setString(counter++, user.getEmail());
            pstmt.setString(counter++, user.getPassword());
            pstmt.setString(counter++, user.getRole());
            pstmt.setString(counter, user.getLang());

            pstmt.execute();
            connection.commit();
            generatedKeys = pstmt.getGeneratedKeys();

            if (generatedKeys.next()) {
                user.setId(generatedKeys.getInt(Fields.GENERATED_KEY));
            }
        } catch (SQLException e) {
            rollback(connection);
            LOG.error("Can not create a user", e);
        } finally {
            close(connection);
            close(pstmt);
            close(generatedKeys);
        }
    }
  ....
}

我应该如何测试?

如果我想测试一个DAO类,那么我需要创建一个DataSource模拟,Connection模拟,ResultSet模拟等吗?如此不测试数据库本身?

但是,如果我还想测试dao和数据库的行为怎么办?

您能否提供一些代码示例,可能有用的链接,并显示实现此目的的最佳方法?


问题答案:

这是使用Mockito测试UserDAO的一个很好的开始。该代码使用了大量的Mockito功能,因此您可以了解如何使用它们。如果您有任何问题,请告诉我。

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.runner.RunWith;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import org.mockito.Mock;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class TestUserDAO {

    @Mock
    DataSource mockDataSource;
    @Mock
    Connection mockConn;
    @Mock
    PreparedStatement mockPreparedStmnt;
    @Mock
    ResultSet mockResultSet;
    int userId = 100;

    public TestUserDAO() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() {
    }

    @Before
    public void setUp() throws SQLException {
        when(mockDataSource.getConnection()).thenReturn(mockConn);
        when(mockDataSource.getConnection(anyString(), anyString())).thenReturn(mockConn);
        doNothing().when(mockConn).commit();
        when(mockConn.prepareStatement(anyString(), anyInt())).thenReturn(mockPreparedStmnt);
        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);
        when(mockResultSet.getInt(Fields.GENERATED_KEYS)).thenReturn(userId);
    }

    @After
    public void tearDown() {
    }

    @Test
    public void testCreateWithNoExceptions() throws SQLException {

        UserDAO instance = new UserDAO(mockDataSource);
        instance.create(new User());

        //verify and assert
        verify(mockConn, times(1)).prepareStatement(anyString(), anyInt());
        verify(mockPreparedStmnt, times(6)).setString(anyInt(), anyString());
        verify(mockPreparedStmnt, times(1)).execute();
        verify(mockConn, times(1)).commit();
        verify(mockResultSet, times(2)).next();
        verify(mockResultSet, times(1)).getInt(Fields.GENERATED_KEYS);
    }

    @Test(expected = SQLException.class)
    public void testCreateWithPreparedStmntException() throws SQLException {

         //mock
         when(mockConn.prepareStatement(anyString(), anyInt())).thenThrow(new SQLException());


        try {
            UserDAO instance = new UserDAO(mockDataSource);
            instance.create(new User());
        } catch (SQLException se) {
            //verify and assert
            verify(mockConn, times(1)).prepareStatement(anyString(), anyInt());
            verify(mockPreparedStmnt, times(0)).setString(anyInt(), anyString());
            verify(mockPreparedStmnt, times(0)).execute();
            verify(mockConn, times(0)).commit();
            verify(mockResultSet, times(0)).next();
            verify(mockResultSet, times(0)).getInt(Fields.GENERATED_KEYS);
            throw se;
        }

    }
}


 类似资料:
  • } ---编辑1--更改 根据注释,断言是失败的。

  • 我有一个类需要进行单元测试: 我有一个测试用例: 当我运行测试用例时,没有使用ActiveMQConnectionFactory的模拟对象。相反,正在使用实际的实现,并且正在建立TCP连接: 我尝试了Powermockito和Mockito,但都失败了。如何模拟对象,如何成功运行测试用例? 我是单元测试新手,试图从各个社区获得帮助,但没有找到合适的答案。任何帮助都将不胜感激。谢谢

  • 我想测试一个当前数据的方法,使用id指示它应该是什么类型的记录,并“替换”数据。 我写了一个测试方法的开头,但我在某个点上卡住了,例如,我不知道如何正确实现断言以使测试通过。 服务 控制器 测试方法(发票1是一个示例对象,其中包含构造函数传递的数据以测试更新记录)这就是我停下来的地方,因为我不知道如何做出断言来理解它

  • 我有DaoImpl类: 我的测试是: 测试是成功的,但是当我运行具有覆盖率的junit测试时,它显示方法没有被覆盖,因此我的整体单元测试行覆盖率低于要求。我们能涵盖那部分吗?如果是,我们怎么做?谢了。

  • 我有一个简单的类,但带有匿名代码块。我需要用测试来覆盖这门课。 和测试: 注释行不工作。日志:需要但未调用:dao.DeleteAllByStatusAndDate(,isA(java.util.date));->在com.nxsystems.dw.publisher.handler.CleanerTaskTest.SuccessfulScenario(CleanerTaskTest.java:5

  • 问题内容: 我对Java单元测试非常陌生,听说Mockito框架对于测试非常有用。 我已经开发了一个REST Server(CRUD方法),现在我想对其进行测试,但是我不知道如何? 我什至不知道该测试程序应该如何开始。我的服务器应该在本地主机上运行,​​然后在该URL上进行调用(例如,本地主机:8888)? 这是我到目前为止尝试过的方法,但是我很确定这不是正确的方法。 这是方法的代码。 在此测试用