5

I'm using Dropwizard framework with JDBI and h2-in-memory for my test purposes. Also I've written my DAOs, and now I want to test them with unit tests. I came along the DBUnit which seem to fit my requirements.

But how to integrate it with JDBI and fill it with test data?

VanDavv
  • 836
  • 2
  • 13
  • 38

1 Answers1

11

I implemented it like this:

I created a base dao class that sets up my DW environment to build a DBI instance for me. This looks like that:

@BeforeClass
    public static void setup() {
        env = new Environment( "test-env", Jackson.newObjectMapper(), null, new MetricRegistry(), null );
        dbi = new DBIFactory().build( env, getDataSourceFactory(), "test" );
        dbi.registerArgumentFactory(new JodaDateTimeArgumentFactory());
        dbi.registerMapper(new JodaDateTimeMapper(Optional.absent()));
    }

    static DataSourceFactory getDataSourceFactory()
    {
        DataSourceFactory dataSourceFactory = new DataSourceFactory();
        dataSourceFactory.setDriverClass( "org.h2.Driver" );
        dataSourceFactory.setUrl( "jdbc:h2:mem:testDb" );
        dataSourceFactory.setUser( "sa" );
        dataSourceFactory.setPassword( "" );
        return dataSourceFactory;
    }

    public static DBI getDbi() {
        return dbi;
    }

    public static Environment getEnvironment() {
        return env;
    }

Not this will create a Datasource for you pointing to your in-memory database.

No in the actual test you can use the DBI instance to create your DAOs before the test:

DaoA dao;
DaoB otherDao;

@Before
public void setupTests() throws IOException {
    super.setupTests();
    dao = dbi.onDemand(DaoA.class);
    otherDao = dbi.onDemand(DaoB.class);
}

With this your good to go and you can start testing. Hope that helps.

Artur

Edit for init:

My tests initialise themselves as well. For that I use dbi directly to execute sql scripts. For example, a test is associated with a test1.sql script that is a test classpath resource. In that case, all I need to do is read that script and run it before the test. For example like this:

            StringWriter writer = new StringWriter();
            InputStream resourceStream = this.getClass().getResourceAsStream("/sql/schema.sql");
            if(resourceStream == null ) {
                throw new FileNotFoundException("schema not found");
            }
            IOUtils.copy(resourceStream, writer);
            Handle handle = null;
            try {
                handle = dbi.open();
                handle.execute(writer.toString());
                handle.commit();
            } finally {
                handle.close();
                if(resourceStream != null) {
                    resourceStream.close();
                }
                writer.close();
            }
pandaadb
  • 6,306
  • 2
  • 22
  • 41
  • Yes, thank you! This is what i was looking for. But for test purposes I would like to fill my test database with my test data (to test the GET method), and my goal is to make my tests independent of eachother. Is there an elegant way to fill my database with a model class other than manually querying jdbi database? – VanDavv Mar 07 '16 at 13:33
  • Your code is not working. `IOUtils.copy(resourceStream, writer);` - this is incorrect `super.setupTests();` - which class are You extending? – VanDavv Mar 07 '16 at 20:29
  • My code is not a full copy of my production code. The IOUtils are apache-commons-io. All they do is copy an input stream. The super.setupTests() call is calling the part with the IOUtils. It sets up my tests, as the method suggests. So it will run the init scripts, initialise the DBI, and then return to create the DAOs of that DBI instance. – pandaadb Mar 08 '16 at 10:33
  • I am getting error while opening handle on dbi org.apache.tomcat.jdbc.pool.ConnectionPool init SEVERE: Unable to create initial connections of pool. org.h2.jdbc.JdbcSQLException: Database "mem:test" not found [90013-193] – MayurB Jan 19 '17 at 09:15
  • Hi, i would need some more info on thtat. I believe the above solution is for a rather old version of DW (0.8 maybe) and the latest have heaps of updates on their dependencies. – pandaadb Jan 30 '17 at 09:11
  • @pandaadb I'm having a lot of problems with the use of `<` in my `@SqlUpdate`. If the `<` is being used as a template to use `@Define`, I get `JdbcSQLException` error. If it is escaped as `\\<` to use as less than, I also get `JdbcSQLException`. Any tups on this? – Kousha Feb 12 '18 at 20:40