Testing database operations

The database service is a good fit for writing tests.

We first need to deploy the database verticle. We will configure the JDBC connection to be HSQLDB with an in-memory storage, and upon success we will fetch a service proxy for our test cases.

Since these operations are involving, we leverage the JUnit before / after life-cycle methods:

  1. private Vertx vertx;
  2. private WikiDatabaseService service;
  3. @Before
  4. public void prepare(TestContext context) throws InterruptedException {
  5. vertx = Vertx.vertx();
  6. JsonObject conf = new JsonObject() (1)
  7. .put(WikiDatabaseVerticle.CONFIG_WIKIDB_JDBC_URL, "jdbc:hsqldb:mem:testdb;shutdown=true")
  8. .put(WikiDatabaseVerticle.CONFIG_WIKIDB_JDBC_MAX_POOL_SIZE, 4);
  9. vertx.deployVerticle(new WikiDatabaseVerticle(), new DeploymentOptions().setConfig(conf),
  10. context.asyncAssertSuccess(id -> (2)
  11. service = WikiDatabaseService.createProxy(vertx, WikiDatabaseVerticle.CONFIG_WIKIDB_QUEUE)));
  12. }
  1. We only override some of the verticle settings, the others will have default values.

  2. asyncAssertSuccess is useful to provide a handler that checks for the success of an asynchronous operation. There is a variant with no arguments, and a variant like this one where we can chain the result to another handler.

Cleaning up the Vert.x context is straightforward, and again we use asyncAssertSuccess to ensure that no error was encountered:

  1. @After
  2. public void finish(TestContext context) {
  3. vertx.close(context.asyncAssertSuccess());
  4. }

The service operations are essentially CRUD operations, so a JUnit test case combining all of them is a fine way to test:

  1. @Test
  2. public void crud_operations(TestContext context) {
  3. Async async = context.async();
  4. service.createPage("Test", "Some content", context.asyncAssertSuccess(v1 -> {
  5. service.fetchPage("Test", context.asyncAssertSuccess(json1 -> {
  6. context.assertTrue(json1.getBoolean("found"));
  7. context.assertTrue(json1.containsKey("id"));
  8. context.assertEquals("Some content", json1.getString("rawContent"));
  9. service.savePage(json1.getInteger("id"), "Yo!", context.asyncAssertSuccess(v2 -> {
  10. service.fetchAllPages(context.asyncAssertSuccess(array1 -> {
  11. context.assertEquals(1, array1.size());
  12. service.fetchPage("Test", context.asyncAssertSuccess(json2 -> {
  13. context.assertEquals("Yo!", json2.getString("rawContent"));
  14. service.deletePage(json1.getInteger("id"), v3 -> {
  15. service.fetchAllPages(context.asyncAssertSuccess(array2 -> {
  16. context.assertTrue(array2.isEmpty());
  17. async.complete(); (1)
  18. }));
  19. });
  20. }));
  21. }));
  22. }));
  23. }));
  24. }));
  25. async.awaitSuccess(5000); (2)
  26. }
  1. This is where the sole Async eventually completes.

  2. This is an alternative to exiting the test case method and relying on a JUnit timeout. Here the execution on the test case thread waits until either the Async completes or the timeout period elapses.