Java 单元测试数据库调用
我有一个带有静态函数的类,这些函数执行数据库操作,如保存、检索和删除 我的数据库类:Java 单元测试数据库调用,java,unit-testing,mockito,powermock,powermockito,Java,Unit Testing,Mockito,Powermock,Powermockito,我有一个带有静态函数的类,这些函数执行数据库操作,如保存、检索和删除 我的数据库类: public final class DbUtils { static { DB_USER = //get from secure server DB_PASSWORD = //get from secure server } private static Connection establishConnection() { } p
public final class DbUtils {
static {
DB_USER = //get from secure server
DB_PASSWORD = //get from secure server
}
private static Connection establishConnection() {
}
private static void closeConnection(Connection connection) {
}
public static boolean saveObject(final Object graph, final Object map) {
Connection connection = establishConnection();
try {
byte[] bgraph = ConvertToByte(graph);
byte[] bmap = ConvertToByte(map);
statement = connection.prepareStatement("INSERT IGNORE INTO " + TABLE_NAME + " VALUES (?,?)");
statement.setObject(1, graph);
statement.setObject(2, map);
statement.executeUpdate();
//Close statement within try catch
} catch(Exception e) { // also other exception
//catch to catch all type of exception
}
closeConnection(connection);
return true;
}
public static Map<String, Object> retrieveObject(final String key) {
Connection connection = establishConnection();
//read byte and convert to object
closeConnection(connection);
return map;
}
public static boolean deleteObject(final String key) {
Connection connection = establishConnection();
//delete all object except object with key
closeConnection(connection);
return (affectedRow >= 1);
}
}
公共最终类DbUtils{
静止的{
DB_USER=//从安全服务器获取
DB_PASSWORD=//从安全服务器获取
}
专用静态连接建立连接(){
}
专用静态连接(连接连接){
}
公共静态布尔保存对象(最终对象图、最终对象映射){
连接=建立连接();
试一试{
字节[]bgraph=ConvertToByte(图形);
字节[]bmap=转换字节(map);
语句=connection.prepareStatement(“将忽略插入“+表名+”值(?,)”;
语句.setObject(1,图形);
语句.setObject(2,map);
语句。executeUpdate();
//try-catch中的Close语句
}catch(异常e){//还有其他异常
//捕获以捕获所有类型的异常
}
闭合连接(连接);
返回true;
}
公共静态映射检索对象(最终字符串键){
连接=建立连接();
//读取字节并转换为对象
闭合连接(连接);
返回图;
}
公共静态布尔deleteObject(最终字符串键){
连接=建立连接();
//删除除具有键的对象之外的所有对象
闭合连接(连接);
返回(affectedRow>=1);
}
}
我编写了一个单元测试来测试它,如下所示:
@RunWith(PowerMockRunner.class)
@PrepareForTest(DbUtils.class)
@SuppressStaticInitializationFor("DbUtils")
public class DbUtilsTest {
@Mock
Connection connection;
@Mock
ModuleDependencyGraph dependencyGraph;
@Mock
private Map<String , String> moduleSDF;
@Test
public void testSaveObject() throws Exception {
PowerMockito.spy(DbUtils.class);
PowerMockito.doReturn(connection).when(DbUtils.class, "establishConnection");
Assert.assertTrue(DbUtils.saveObject(dependencyGraph, moduleSDF));
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(DbUtils.class)
@SuppressStaticInitializationFor(“DbUtils”)
公共类DbUtilsTest{
@嘲弄
连接;
@嘲弄
模块依赖图依赖图;
@嘲弄
私有地图模块df;
@试验
public void testSaveObject()引发异常{
spy(DbUtils.class);
doReturn(连接).when(DbUtils.class,“建立连接”);
Assert.assertTrue(DbUtils.saveObject(dependencyGraph,moduleSDF));
}
}
当我尝试运行这个单元测试时,我在语句=connection.prepareStatement
行得到了一个空指针错误,我想这是意料之中的,因为我没有正确模拟连接。如何正确模拟连接?我编写saveObject
测试的方式是否正确?我是单元测试新手,所以我不知道最佳实践以及如何涵盖所有情况
@Mock
Statement statement;
doReturn(statement).when(connection).prepareStatement(anyString());
doNothing().when(statement).setObject(any(), any());
doNothing().when(statement).executeUpdate();
这只是在使用Mockito。您也可以使用PowerMockito。它仍然可以工作。我应该在PowerMockito.doReturn(连接)之后添加这些行。对吗?除了
@Mock
部分。setObject
和executeUpdate
都给出了错误。由于IDE没有建议任何导入,是否有任何导入要添加setObject
正在给出找不到符号
错误,并且executeUpdate
正在给出找不到适合executeUpdate的方法(无参数)
错误。setObject和executeUpdate是语句上的方法
类解决了该错误setObject
不是Statement
类上的方法,但它在PreparedStatement
上,并且executeUpdate
需要字符串作为sql查询作为参数执行。我将statement
的类型更改为PreparedStatement
,并将setObject
行修改为PowerMockito.doNothing();PowerMockito.doNothing().when(语句).setObject(2,any())代码>但是现在我发现参数匹配器的使用无效!需要2个匹配器,1个记录:->在DbUtilsTest.testSaveObject(DbUtilsTest.java:52)
(第52行是setObject
,1作为参数索引。不能将实值(1,2)与匹配器(any())混合。将setObject中的1和2更改为eq(1)
和eq(2)