是否有某种JDBC驱动程序只是忽略了数据库调用?
对于开发,我正在将应用程序迁移到虚拟机。在这里,我只想处理GUI部分。但是应用程序向数据库发出了几个请求,这些请求甚至无法启动应用程序。我不想在此时更改应用程序代码,因为数据库几乎是耦合的。
所以我认为可能有一个JDBC驱动程序只返回查询的空结果。
答案 0 :(得分:12)
我决定编写一个自己的简单模拟驱动程序。这非常直接,做了我想要的。我可以通过配置文件切换应用程序的数据库驱动程序,这样我就可以让应用程序以简单的方式使用我的驱动程序。
然后我扩展了驱动程序以返回它从CSV文件解析的数据。我在谷歌代码上发布了代码,也许其他人可以使用它:dummyjdbc
答案 1 :(得分:10)
作为Mocking framewroks的一部分,有一些“void”JDBC驱动程序,例如来自MockDriver的Mockrunner。
但使用它需要一些编码。
这是因为当Java应用程序连接到数据库时,它提供了jdbc:mysql://localhost
形式的JDBC URL。系统正在搜索在其中注册的驱动程序以处理此类URL并选择正确的驱动程序。关于哪种URL类型驱动程序支持的信息包含在驱动程序本身中,并且模拟驱动程序不可能在其中保存所有已知的URL类型 - 那里没有通配符,任何列表都不会满。
因此,如果您能够在连接到数据库之前在应用程序中调用JDBCMockObjectFactory.registerMockDriver() - 它将完成这项工作。如果不是 - 我不认为这是可能的。但是,稍微修改一下驱动程序代码就可以了......但是再次 - 需要编码。
答案 2 :(得分:5)
jOOQ附带MockConnection
,可以提供MockDataProvider
,这比完整的JDBC API更容易实现。这篇博客文章展示了如何使用MockConnection:
http://blog.jooq.org/2013/02/20/easy-mocking-of-your-database/
一个例子:
MockDataProvider provider = new MockDataProvider() {
// Your contract is to return execution results, given a context
// object, which contains SQL statement(s), bind values, and some
// other context values
@Override
public MockResult[] execute(MockExecuteContext context)
throws SQLException {
// Use ordinary jOOQ API to create an org.jooq.Result object.
// You can also use ordinary jOOQ API to load CSV files or
// other formats, here!
DSLContext create = DSL.using(...);
Result<MyTableRecord> result = create.newResult(MY_TABLE);
result.add(create.newRecord(MY_TABLE));
// Now, return 1-many results, depending on whether this is
// a batch/multi-result context
return new MockResult[] {
new MockResult(1, result)
};
}
};
// Put your provider into a MockConnection and use that connection
// in your application. In this case, with a jOOQ DSLContext:
Connection connection = new MockConnection(provider);
DSLContext create = DSL.using(connection, dialect);
// Done! just use regular jOOQ API. It will return the values
// that you've specified in your MockDataProvider
assertEquals(1, create.selectOne().fetch().size());
还有MockFileDatabase
,它可以帮助您通过编写如下文本文件来匹配虚拟结果和SQL字符串:
# This is a sample test database for MockFileDatabase
# Its syntax is inspired from H2's test script files
# When this query is executed...
select 'A' from dual;
# ... then, return the following result
> A
> -
> A
@ rows: 1
# Just list all possible query / result combinations
select 'A', 'B' from dual;
> A B
> - -
> A B
@ rows: 1
select "TABLE1"."ID1", "TABLE1"."NAME1" from "TABLE1";
> ID1 NAME1
> --- -----
> 1 X
> 2 Y
@ rows: 2
答案 3 :(得分:2)
我的框架Acolyte是为此目的而设计的经过测试的JDBC驱动程序(模拟,测试......):https://github.com/cchantep/acolyte
它已经在几个开源项目中使用,无论是使用vanilla Java还是使用其Scala DSL:
// Register prepared handler with expected ID 'my-unique-id'
acolyte.Driver.register("my-unique-id", handler);
// then ...
Connection con = DriverManager.getConnection(jdbcUrl);
// ... Connection |con| is managed through |handler|
答案 4 :(得分:1)
我自己从未听说过这样的司机。如果找不到,可以使用像HSQLDB这样的数据库。您可以将其配置为使用内存表,因此不会将任何其他内容写入磁盘。但是,您必须使用不同的连接字符串。
答案 5 :(得分:1)
如果你想进行单元测试,而不是集成测试 您可以使用一种非常基本且简单的方法,仅使用Mockito,如下所示:
public class JDBCLowLevelTest {
private TestedClass tested;
private Connection connection;
private static Driver driver;
@BeforeClass
public static void setUpClass() throws Exception {
// (Optional) Print DriverManager logs to system out
DriverManager.setLogWriter(new PrintWriter((System.out)));
// (Optional) Sometimes you need to get rid of a driver (e.g JDBC-ODBC Bridge)
Driver configuredDriver = DriverManager.getDriver("jdbc:odbc:url");
System.out.println("De-registering the configured driver: " + configuredDriver);
DriverManager.deregisterDriver(configuredDriver);
// Register the mocked driver
driver = mock(Driver.class);
System.out.println("Registering the mock driver: " + driver);
DriverManager.registerDriver(driver);
}
@AfterClass
public static void tearDown() throws Exception {
// Let's cleanup the global state
System.out.println("De-registering the mock driver: " + driver);
DriverManager.deregisterDriver(driver);
}
@Before
public void setUp() throws Exception {
// given
tested = new TestedClass();
connection = mock(Connection.class);
given(driver.acceptsURL(anyString())).willReturn(true);
given(driver.connect(anyString(), Matchers.<Properties>any()))
.willReturn(connection);
}
}
您可以测试各种场景,例如在任何其他Mockito测试中,例如。
@Test
public void shouldHandleDoubleException() throws Exception {
// given
SomeData someData = new SomeData();
given(connection.prepareCall(anyString()))
.willThrow(new SQLException("Prepare call"));
willThrow(new SQLException("Close exception")).given(connection).close();
// when
SomeResponse response = testClass.someMethod(someData);
// then
assertThat(response, is(SOME_ERROR));
}
答案 6 :(得分:0)
如果您正在使用Spring,请创建自己的实现Datasource的类,并让方法不执行任何操作。