【问题标题】:ResultSet is null while mocking databaseMetaData.getTables() method模拟 databaseMetaData.getTables() 方法时 ResultSet 为空
【发布时间】:2021-10-08 07:46:07
【问题描述】:

我正在尝试为一个类编写一个单元测试用例,用于检查数据库中是否存在表。我使用了DatabaseMetadata 接口和Resultset 来实现它。现在我正在尝试为此编写一个单元测试用例,但是在模拟时

数据库元数据 getTables()

方法,我的结果集为空。谁能告诉我我做错了什么?还有没有更好的方法来检查数据库中的表?

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;

@Component
public class DataBaseTableScanner {
    
    public DataBaseTableScanner() {
        super();
    }
    
    private DataSource datasource;
    
    @Autowired
    public DataBaseTableScanner(DataSource datasource) {
        this.datasource = datasource;
    }
    
    public void setDataSource(DataSource datasource) {
        this.datasource = datasource;
    }
    
    
    public boolean checkForTableInDataBase(String entityName) throws SQLException {     
        try(Connection con = datasource.getConnection()){
            DatabaseMetaData databaseMetaData = con.getMetaData();
            String tableName = entityName.toUpperCase();
            String[] types = {"TABLE"};
            resultSet = databaseMetaData.getTables(null, null, tableName, types);
            boolean tableExistFlag = resultSet.next();
            if(tableExistFlag) {
                System.out.println("Check Table:: "+ tableName + " :Table exits in Database!!");
            }else {
                System.out.println("Check Table:: "+ tableName + " :Table does not exits in Database!!");
            }
            return tableExistFlag;
            
        }
    }
}

我的单元测试用例


import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.BeforeMapping;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class DataBaseTableScannerTest {
    
    @InjectMocks
    DataBaseTableScanner dataBaseTableScanner;
    
    @Mock
    DataSource datasource;
    
    @Mock
    Connection connection;
    
    @Mock
    DatabaseMetaData databaseMetaData;
    
    @Mock
    ResultSet resultSet;
    
    
    @Before
    public void setUp() throws TenantResolvingException, TenantNotFoundException, SQLException {
    
        dataBaseTableScanner.setDataSource(datasource);

        
        when(datasource.getConnection()).thenReturn(connection);
        when(connection.getMetaData()).thenReturn(databaseMetaData);
        String tableName = null;
        String[] types = null;
        //      String tableName = "task";
        //      String[] types = {"TABLE"};
         when(databaseMetaData.getTables(null, null, tableName, types)).thenReturn(resultSet);
        
    }
    
    
    @Test
    public void testIsTableExists() throws SQLException {
        boolean tbexists = dataBaseTableScanner.checkForTableInDataBase("task");
        assertTrue(tbexists);
    }

【问题讨论】:

    标签: java unit-testing jdbc junit mockito


    【解决方案1】:

    你用参数databaseMetaData.getTables(null, null, null, null))模拟方法,因为在setup方法中:

    String tableName = null;
    String[] types = null;
    

    但是当你调用checkForTableInDataBase方法时,里面会调用getTables方法,参数不同:

    String tableName = entityName.toUpperCase();
    String[] types = {"TABLE"};
    

    所以你应该重写你 when 方法:

     when(databaseMetaData.getTables(null, null, "task".toUpperCase(), {"TABLE"})).thenReturn(resultSet);
    

    当然,只有在您使用“任务”作为dataBaseTableScanner.checkForTableInDataBase() 的输入参数的情况下它才会起作用

    【讨论】:

    • 您好@Anatolii Chub,谢谢您的回复。我也理解了解决方案,现在我知道 when 在 mockito 中的工作方式。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多