Programmable JDBC driver for mocking
I'm trying to test legacy Java application, without an ability to re-factor its code at the moment. All I need to do is to understand what SQL requests it is sending through JDBC and when. All these requests I'd like to protocol to a plain text fi开发者_StackOverflowle for future review.
I need to develop a custom JDBC driver which will fool the application, and behave like a normal driver (will accept request, return some values, fail on certain conditions, etc). A mock structure, as usual...
The question is - do you know any existing frameworks for this task? Ideally I would like to have an ability to configure my driver's behavior through, say, XML file.
p6spy wraps an existing jdbc connection, and allows you to e.g. see what goes back and forth.
See http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-solution/ for instructions.
If you want to do unit tests, not an integration tests, than you can use a very basic and simple approach, using Mockito only, like this:
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);
given(connection.prepareCall(anyString())).willReturn(statement);
}
}
Than you can test various scenarios, like in any other Mockito test e.g.
@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));
}
精彩评论