Introduction

Motivation

When we are preparing data of RDB for tests, the tedious and tricky part is to write correct DML for data insertion. Foxglove is a library that helps you to generating data by auto schema-inspection and table facet(rules to generate data).

While preparing data for unit tests over databases, the key things are:

  1. Preparing values for columns in WHERE clause of SQL or clause may FILTERING data(e.g. INNER JOIN).

  2. Some critical values to be asserted or counting number of results affected by exercised SQL.

  3. While tearing down the tests, you may like to delete only the data you have inserted.

    • Specify some fixed values to irrelevant columns could help

That is, how Foxglove helps you:

  1. Just provide values for specified columns.

  2. Give the critical values you need to check.

  3. Don’t have to care about irrelevant, non-nullable(and no default value) columns.

Other data that is irrelevant to your tests will be generated automatically by Foxglove.


Preparing data
// Generates 4 rows with "cr_brand "fixed to "Toyota" and
// 4 different values on "cr_model"
var facet = JdbcTableFacet.builder(TABLE_CAR)
    .numberOfRows(4)
    .column("cr_brand")
        .fixed("Toyota")
    .column("cr_model")
        .roundRobin("Corolla", "Camry", "RAV4", "Prius")
    .build();

new JdbcDataGenerator(getDataSource())
    .generate(facet);

The data could be used for:

  1. There could be 0 ~ 1 matched row for any query of the SQL

    SELECT *
    FROM ap_car
    WHERE cr_brand = ?
        AND cr_model = ?
  2. Since cr_created_at will be generated randomly by default, you can check the values of the column for the correctness of ordering.

    SELECT *
    FROM ap_car
    WHERE cr_brand = ?
    ORDER BY cr_created_at DESC

Requirements

Installation

Maven pom.xml
<repositories>
    <repository>
        <id>foxglove-repo</id>
        <name>Foxglove Maven Repository</name>
        <url>https://maven.pkg.github.com/mikelue/foxglove</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

<dependency>
    <groupId>guru.mikelue.foxglove</groupId>
    <artifactId>core</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>test</scope>
</dependency>
GitHub Maven registry authentication($HOME/.m2/settings.xml)
<servers>
    <server>
        <id>foxglove-repo</id>
        <username>mikelue</username>
        <password>your_token</password>
    </server>
</servers>

Don’t forget to create a PAT(personal access token) on GitHub.


Gradle
repositories {
    maven {
        name 'foxglove-repo'
        url 'https://maven.pkg.github.com/mikelue/foxglove'
    }
}

testImplementation 'guru.mikelue.foxglove:core:1.0-SNAPSHOT'

SBT
resolvers += "foxglove-repo" at "https://maven.pkg.github.com/mikelue/foxglove"

libraryDependencies += "guru.mikelue.foxglove" % "core" % "1.0-SNAPSHOT" % Test

ivysettings.xml
<ivysettings>
    <settings defaultResolver="chain"/>
    <resolvers>
        <chain name="chain">
            <ibiblio name="foxglove-repo"
                     m2compatible="true"
                     root="https://maven.pkg.github.com/mikelue/foxglove"
                     pattern="[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"/>
        </chain>
    </resolvers>
</ivysettings>
Ivy
<dependency org="guru.mikelue.foxglove" name="core" rev="1.0-SNAPSHOT" conf="test"/>

Credits

Thanks to Instancio project for its excellent data generation capabilities.