Testing

Testing #

This documentation is no longer applicable. Updated documentation will be provided soon.

Automated testing is a critical part of application quality assurance. The testing utilities are optimized to easily allow you to send real HTTP requests to your application.

Below is an example of how to use JUnit and the ApplicationClient class:

import diego.Application
import diego.utils.test.ApplicationClient
import diego.utils.httpclient.HttpClientRequest
import diego.utils.httpclient.HttpClientResponse
import org.junit.jupiter.api.*

import java.util.function.Supplier

import static org.junit.jupiter.api.Assertions.assertEquals

class ApplicationTest {
  /* Create an ApplicationClient using the factory method */
  final static ApplicationClient client = 
      ApplicationClient.create(Launcher::buildApplication)

  @Test
  void testIndexRoute() {
    final HttpClientRequest request = client.createRequest("/")
    /* Send the request to the server and inspect the response */
    client.send(request) { response ->
      assertEquals(200, response.statusCode)
    }
  }

  @AfterClass
  static void afterClass() {
    /* Finally, we close the client when all tests have completed. */
    client.close()
  }
}

The above test class should be pretty straightforward for anyone with a JUnit background. We create a server, create a request, send the request and finally, inspect the response.

The ApplicationClient class uses the built-in HTTP Client under the hood, so check out that chapter to see all the possibilities for building your requests.

Unit testing and the persistence layer #

The Service class has a dependency on the Database class which in turn relies on an instance of Hibernate’s SessionFactory in order to work. This dependency chain is automatically created whenever you call Application.create(). However, it would make for some inefficient testing to require a running application in order to test a simple Service.

The Helpers class has some useful methods for bootstrapping the dependency container without starting your application. You can even specify a configuration file if you don’t want to use your application’s default configuration.

To build the dependency container, we call Helpers.initializeContext(). To get an instance of our Service for unit tests, we call Helpers.get(Class<?>).

An example:

import diego.utils.Helpers

class CustomerModelTest {
  static CustomerService customerService

  @BeforeClass
  static void beforeClass() {
    /* Optionally specify the config file in 
    src/test/resources/test.conf */
    Helpers.initializeContext("test.conf")
    /* Get an instance of CustomerService from the dependency container. */
    customerService = Helpers.get(CustomerService)
  }

  @Test
  void overdueCustomersTest() {
    /* Use your CustomerService instance as usual. */
    def customers = customerService.findOverdueAccounts()
    assertNotEmpty(customers)
  }

}

A couple notes on the Helpers class:

  • Calling Helpers.initializeContext() multiple times with the same arguments will not trigger a rebuild of the dependency container.
  • Calling Helpers.get(Class<?>) will initialize the dependency container with the default configuration if the container has not yet been initialized.

Running database scripts #

While testing, you may wish to reset the database to a consistent state for each individual unit test. One way of doing that is by using an SQL script. Handily, Diego comes with a utility for running SQL scripts against any database specified in your application configuration.

To use it, place your SQL script in the src/test/resources directory then execute the script using the SqlScriptRunner.executeScript() method.

import static diego.utils.Helpers.get

class SomeTestClass {
  
  private static Database db = get(Database)
  private static SqlScriptRunner scriptRunner = get(SqlScriptRunner)
  
  
  @BeforeEach
  void resetDatabase() {
      scriptRunner.executeScript("seed.sql") // src/test/resources/seed.sql
      db.session.clear() // Clear the session.
  }
}

Next: Configuration