java - 如何使用 Mockito 测试我的 DAO 方法?

标签 java unit-testing junit mockito dao

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

示例代码:尝试根据给定的选择器(< 或 >)从数据库中获取选举结果。

public class AdminDaoImpl extends DaoImpl implements AdminDao {

    private final Logger LOGGER = Logger.getLogger(getClass().getName());

    @Override
    public ElectionListResponse getElections(char selector) {
        ElectionListResponse electionListResponse = new ElectionListResponse();

        String query = NamedQueries.GET_ELECTIONS_BEGIN + selector + NamedQueries.GET_ELECTIONS_END;

        try {
            con = sqlConnection.getConnection();
            stmt = con.prepareStatement(query);
            rs = stmt.executeQuery();

            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

            while (rs.next()) {
                Election election = new Election();
                election.setElectionID(rs.getInt("id"));
                election.setElectionName(rs.getString("name"));
                election.setStartDate(df.format(rs.getDate("startDate")));
                election.setEndDate(df.format(rs.getDate("endDate")));
                electionListResponse.addElection(election);
            }
            return electionListResponse;
        } catch (SQLException e) {
            LOGGER.log(Level.SEVERE, "Cant get elections. ", e);
        } finally {
            closeConnection();
        }
        return null;
    }

这是上面代码扩展的 DAO:

public abstract class DaoImpl implements Dao {

    private final Logger LOGGER = Logger.getLogger(getClass().getName());

    @Inject
    public SQLConnection sqlConnection;

    public Connection con;
    public PreparedStatement stmt;
    public ResultSet rs;

    public void closeConnection() {
        try {
            if (con != null) con.close();
            if (stmt != null) stmt.close();
            if (rs != null) con.close();
        } catch (SQLException e) {
            LOGGER.log(Level.SEVERE, "Can't close connection with database. ", e);
        }
    }
}

我尝试应用一些在网上找到的代码,这就是我目前拥有的代码:

@RunWith(MockitoJUnitRunner.class)
public class AdminDaoImplTest {

    @Mock
    DataSource mockDataSource;
    @Mock
    Connection mockConn;
    @Mock
    PreparedStatement mockPreparedStmnt;
    @Mock
    ResultSet mockResultSet;

    @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.executeQuery()).thenReturn(mockResultSet);
        when(mockResultSet.next()).thenReturn(Boolean.TRUE, Boolean.FALSE);
    }

    @After
    public void tearDown() {
    }

    @Test
    public void testCreateWithNoExceptions() throws SQLException {

        ElectionListResponse electionListResponse = new ElectionListResponse();

        AdminDaoImpl instance = new AdminDaoImpl();
        instance.getElections('>' );

        //verify and assert
        verify(mockConn, times(1)).prepareStatement(anyString(), anyInt());
        verify(mockPreparedStmnt, times(1)).execute();
        verify(mockConn, times(1)).commit();
        verify(mockResultSet, times(2)).next();
        verify(mockResultSet, times(1)).getInt("id");
        verify(mockResultSet, times(1)).getString("name");
        verify(mockResultSet, times(1)).getDate("startDate");
        verify(mockResultSet, times(1)).getDate("endDate");
    }


}

我应该如何测试它?您能提供一些代码示例吗?提前致谢!

空指针:

java.lang.NullPointerException
    at org.han.ica.oose.sneeuwklokje.database.admin.AdminDaoImpl.getElections(AdminDaoImpl.java:28)
    at org.han.ica.oose.sneeuwklokje.database.admin.AdminDaoImplTest.testGetElectionsNoExceptions(AdminDaoImplTest.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

最佳答案

您应该将以下字段添加到测试中:

@InjectMocks
private AdminDaoImpl

这将在您的类中注入(inject)模拟,以便您进行测试。

您得到的 NullPointerException 可以通过这种方式修复(在测试类中):

@Mock
private SQLConnection mockSqlConnection;

在设置方法中添加以下内容:

when(mockSqlConnection.getConnection()).thenReturn(mockConn);

关于java - 如何使用 Mockito 测试我的 DAO 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50696317/

相关文章:

c# - 防止在单元测试中写入数据库 - .NET MVC/Entity Framework

c# - 单元测试错误 - 单元测试适配器无法连接到数据源或读取数据

android - 如何将 Timber 日志重定向到 Junit logcat

java - 如何在 Appium 测试用例中使用带参数的 adb 发送广播?

java - 如何编写复合 Hamcrest 语句(具有逻辑 "or"操作)

java - 给定 2 个对象 : myPanel1 & myPanel2, 如果我们多次将 myPanel2 添加到 myPanel1 中,那么为什么 myPanel1.getWidgetCount() 仍然 = 1;

java - Angular 的请求不要在后端映射我的 API(Spring Boot)

java - onActivityResult 崩溃

java - Android - 将日期从一个 fragment 添加到另一个正在运行的 fragment

c# - 验证 IEnumerable<dynamic> 内容的单元测试