Mock database driver

后端 未结 7 1346
臣服心动
臣服心动 2021-01-17 12:34

Is there some kind of JDBC driver which simply ignores database calls?

For the development I am migrating an application to a virtual machine. Here I want to work on

相关标签:
7条回答
  • 2021-01-17 13:06

    Never heard of such a driver myself. If you don't find one, you could instead use a DB like HSQLDB. You can configure it to use in-memory tables, so nothing else gets written to disk. You would have to use a different connection string, though.

    0 讨论(0)
  • 2021-01-17 13:07

    If you're using Spring, make your own class that implements Datasource and have the methods do nothing.

    0 讨论(0)
  • 2021-01-17 13:08

    I decided to write an own simple mock driver. This was pretty much straight forward and did what I want. I can switch the database driver of the application by a configuration file so I could let the application use my driver on a simple way.

    Then I extended the driver to return data which it parses from CSV files. I published the code on google code maybe someone else can get use of it: dummyjdbc

    0 讨论(0)
  • 2021-01-17 13:09

    jOOQ ships with a MockConnection that can be provided with a MockDataProvider, which is much easier to implement than the complete JDBC API. This blog post shows how to use the MockConnection: http://blog.jooq.org/2013/02/20/easy-mocking-of-your-database/

    An example:

    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());
    

    There is also the MockFileDatabase, which helps you matching dummy results with SQL strings by writing a text file like this:

    # 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
    
    0 讨论(0)
  • 2021-01-17 13:10

    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);
    
        }
    }
    

    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));
    }
    
    0 讨论(0)
  • 2021-01-17 13:19

    My framework Acolyte is a tested JDBC driver designed for such purposes (mock up, testing, ...): https://github.com/cchantep/acolyte

    It already used in several open source projects, either in vanilla Java, or using its 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|
    
    0 讨论(0)
提交回复
热议问题