测试JDBC方法,包括事务方面和连接已关闭

时间:2018-05-04 10:35:37

标签: java testing jdbc

我想为教育目的定义JDBC方法的测试。特别是,除了测试JDBC方法是否具有所需的功能(我已经看到有DBUnit等解决方案)之外,我还想检查这些方法是否验证了特定的要求: - 如果他们在修改时考虑事务性问题(setAutocommit(false)/ commit / rollback) - 如果他们关闭连接, - 等等。

我还没有找到任何测试解决方案来检查是否调用了spectific方法(如前面的方法)。我唯一想到的是尝试使用测试解决方案(例如DBUnit)和AOP(例如AspectJ)来建议是否调用这些方法。

还有其他想法吗? 谢谢!

1 个答案:

答案 0 :(得分:0)

主要有三种方法可以实现您想要实现的目标:

模拟JDBC

热门选项为mockitojmock。例如,使用jmock,您可以编写如下内容:

Mockery m = new Mockery();
Connection c = m.mock(Connection.class);
PreparedStatement s = m.mock(PreparedStatement.class);

m.checking(new Expectations() {{
    oneOf(connection).prepareStatement("test"); will(returnValue(s));
    oneOf(s).setFetchSize(10);
    oneOf(s).execute();
    oneOf(s).getUpdateCount();
    oneOf(s).getWarnings();
    oneOf(s).close();
}});

然后:

// Example code under test:
try (PreparedStatement ps = c.prepareStatement("test")) {
    ps.setFetchSize(10);
    ps.execute();
    ps.getUpdateCount();
    ps.getWarnings();
}

// Finally, check if everything was called as expected.
m.assertIsSatisfied();

实施JDBC

模拟API可以帮助您轻松提供模拟实现,但您可能希望做的不仅仅是模拟驱动程序。在这种情况下,您实际上可以实现JDBC:

class MyConnection implements Connection {
    final Connection delegate;
    public MyConnection(Connection delegate) {
        this.delegate = delegate;
    }
    // ...
}

在这种情况下,您现在可以拦截任何方法调用并开始收集统计信息并在所需方法内部进行断言,而无需修改底层数据库交互,因为所有JDBC调用都将委派给实际驱动程序。

许多图书馆,包括jOOQ,附带用于创建此类代理JDBC对象的实用程序,请参阅例如jOOQ的DefaultConnection。 jOOQ还有一个完整的模拟JDBC实现,可以在这些文章中看到:

但我不确定这是不是你想要的。

(免责声明:我为jOOQ背后的公司工作)

使用AOP

通过使用Javassist之类的工具,您可以拦截某些方法调用,例如所需的JDBC方法调用,并在实际调用之前或之后运行其他逻辑。这与以前实现JDBC的方法的工作方式相同,只是您不必修改测试中的应用程序,因此它是简单验证任务中最不具侵入性和最简单的方法。