### Run Maven clean install Source: https://github.com/database-rider/database-rider/blob/master/rider-examples/jOOQ-DBUnit-flyway-example/README.adoc Use this command to build and install the example project. It compiles the code, runs tests, and packages the project. ```bash mvn clean install ``` -------------------------------- ### dbunit.yml configuration example Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example dbunit.yml configuration file with default values. Used when the @DBUnit annotation is not present. Includes callout markers for mergingStrategy, caseInsensitiveStrategy, raiseExceptionOnCleanUp, expectedDbType, disableSequenceFiltering, disablePKCheckFor, alwaysCleanBefore, alwaysCleanAfter, escapePattern, and datatypeFactory. ```yaml cacheConnection: true cacheTableNames: true leakHunter: false mergeDataSets: false mergingStrategy: METHOD caseInsensitiveStrategy: UPPERCASE raiseExceptionOnCleanUp: false expectedDbType: UNKNOWN disableSequenceFiltering: false disablePKCheckFor: [""] alwaysCleanBefore: false alwaysCleanAfter: false properties: batchedStatements: false qualifiedTableNames: false schema: null caseSensitiveTableNames: false batchSize: 100 fetchSize: 100 allowEmptyFields: false escapePattern: datatypeFactory: !!com.github.database.rider.core.configuration.DBUnitConfigTest$MockDataTypeFactory {} tableType: ["TABLE"] connectionConfig: driver: "" url: "" user: "" password: "" ``` -------------------------------- ### Multiple Prolog variables example Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example showing multiple Prolog variables ($$x$$ and $$y$$) linking rows across tables. This is a TIP for using multiple variables in Prolog assertions. ```yaml table1: - id: $$x$$ name: "name2" - id: $$y$$ name: "name1" table2: - table1_id: $$x$$ - table1_id: $$y$$ ``` -------------------------------- ### DataSet executor example using RiderDSL Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example of using DataSetExecutorImpl and RiderDSL to seed a dataset. The code shows how to create a DataSetConfig and use the executor to create the dataset, then verify the data with JPA queries. ```java import static com.github.database.rider.util.EntityManagerProvider.em; import static com.github.database.rider.util.EntityManagerProvider.instance; @RunWith(JUnit4.class) public class DataSetExecutorIt { public EntityManagerProvider emProvider = instance("executor-it"); private static DataSetExecutorImpl executor; @BeforeClass public static void setup() { executor = DataSetExecutorImpl.instance(new ConnectionHolderImpl(emProvider.getConnection())); } @Test public void shouldSeedUserDataSetUsingExecutor() { DataSetConfig dataSetConfig = new DataSetConfig("datasets/yml/users.yml");<1> executor.createDataSet(dataSetConfig);<2> User user = (User) em().createQuery("select u from User u where u.id = 1").getSingleResult(); assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(1); } } ``` -------------------------------- ### @DataSet annotation usage example Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example of using the @DataSet annotation at method level to configure a dataset with options like strategy, disableConstraints, cleanAfter, and transactional. ```java @Test @DataSet(value ="users.yml", strategy = SeedStrategy.UPDATE, disableConstraints = true,cleanAfter = true,transactional = true) public void shouldLoadDataSetConfigFromAnnotation(){ } ``` -------------------------------- ### Expected dataset YAML file Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example expected dataset file (expectedUsers.yml) used with @ExpectedDataSet. It defines the expected database state after test execution. ```yaml user: - id: 1 name: "expected user1" - id: 2 name: "expected user2" ``` -------------------------------- ### Sample contacts.yml dataset Source: https://github.com/database-rider/database-rider/blob/master/rider-cdi/README.adoc Sample dataset file (contacts.yml) used by the @DataSet annotation in the example test. It defines contact and company records. ```yaml contact: - id: 1 name: "deltaspike" email: "users@deltaspike.apache.org" company_id: 1 - id: 2 name: "querydsl" email: "info@mysema.com" company_id: 2 - id: 3 name: "Spring" email: "spring@pivotal.io" company_id: 3 company: - id: 1 name: "Apache" - id: 2 name: "Mysema" - id: 3 name: "Pivotal" - id: 4 name: "Google" ``` -------------------------------- ### Scriptable dataset with groovy and js Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Scriptable dataset example: YAML dataset uses groovy: and js: prefixes to generate random IDs, and the Java test verifies the user is found and has a non-null ID. ```yaml USER: - ID: groovy:new Random().nextInt() NAME: "@realpestano" - ID: js:Math.floor(Math.random() * 999999) NAME: "@dbunit" ``` ```java @Test @DataSet(value = "datasets/yml/userWithRandomId.yml") public void shouldReplaceUserIdUsingScriptInDataset() { User user = (User) EntityManagerProvider.em().createQuery("select u from User u where u.name = '@dbunit'").getSingleResult(); assertThat(user).isNotNull(); assertThat(user.getId()).isNotNull(); } ``` -------------------------------- ### DataSetException for unmatched theory variables Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example error message raised when variable values in a theory do not match. The exception is a DataSetException indicating that no solution was found for the theory. ```text org.dbunit.dataset.DataSetException: Could not find a solution to theory: IndexedTheory{ user('1', '@realpestano') :- true. user('2', '@dbunit') :- true. tweet(abcdef12345, 'dbunit rules!', '2023-02-25 12:57:13.0', '[null]', '[null]', '2') :- true } given query: (user(X_2, '@realpestano'), tweet(abcdef12345, 'dbunit rules!', __2, __3, __4, X_2)) ``` -------------------------------- ### Create dataset with RiderDSL Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Uses RiderDSL to create a dataset without relying on the @DataSet annotation. This is useful for test runners that do not read annotations (e.g., Cucumber, Spock, Kotlin). The example shows how to set the connection, dataset config, and DBUnit config, then create the dataset. ```java @Test /*same as: @DataSet(value = "yml/user.yml", cleanBefore=true) @DBUnit(caseSensitiveTableNames = false) */ public void shouldSeedDatabaseUsingRiderDSL() { RiderDSL.withConnection(emProvider.connection()) .withDataSetConfig(new DataSetConfig("datasets/yml/user.yml") .cleanBefore(true)) .withDBUnitConfig(new DBUnitConfig().addDBUnitProperty("caseSensitiveTableNames", false)) .createDataSet(); List users = EntityManagerProvider.em().createQuery("select u from User u ").getResultList(); assertThat(users). isNotNull(). isNotEmpty(). hasSize(2); } ``` -------------------------------- ### Export DataSet as Builder with @ExportDataSet Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Two test methods demonstrating @ExportDataSet with BuilderType.DEFAULT and BuilderType.COLUMNS_VALUES. Each generates a Java DataSetBuilder file and an XML dataset file. The full example and related tests are available in the linked ExportDataSetIt.java file. ```java @Test @DataSet("datasets/yml/users.yml") //<1> @ExportDataSet(format = DataSetFormat.XML, outputName = "target/exported/xml/AllTables.xml", builderType = BuilderType.DEFAULT) public void shouldExportDataSetAsBuilderInDefaultSyntax() { //AllTables.java file containing DataSetBuilder code will be generated along with AllTables.xml file. } @Test @DataSet("datasets/yml/users.yml") //<1> @ExportDataSet(format = DataSetFormat.XML, outputName = "target/exported/xml/AllTables2.xml", builderType = BuilderType.COLUMNS_VALUES) public void shouldExportDataSetAsBuilderInColumnValuesSyntax() { //AllTables.java file containing DataSetBuilder code will be generated along with AllTables2.xml file. } ``` -------------------------------- ### Use multiple dataset executors for multiple databases Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Handles multiple databases by creating multiple DataSetExecutorImpl instances, each with its own JDBC connection. Each executor is responsible for a database, and the example seeds a dataset on each executor. Note that the same can be done using @Rule, but then you must provide the executor id in the @DataSet annotation. ```java import static com.github.database.rider.util.EntityManagerProvider.instance; @RunWith(JUnit4.class) public class MultipleExecutorsIt { private static List executors = new ArrayList<>; @BeforeClass public static void setup() { <1> executors.add(DataSetExecutorImpl.instance("executor1", new ConnectionHolderImpl(instance("executor1-pu").getConnection()))); executors.add(DataSetExecutorImpl.instance("executor2", new ConnectionHolderImpl(instance("executor2-pu").getConnection()))); } @Test public void shouldSeedUserDataSet() { for (DataSetExecutorImpl executor : executors) { DataSetConfig dataSetConfig = new DataSetConfig("datasets/yml/users.yml"); executor.createDataSet(dataSetConfig); User user = (User) EntityManagerProvider.instance(executor.getId() + "-pu").em().createQuery("select u from User u where u.id = 1").getSingleResult(); assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(1); } } } ``` -------------------------------- ### Merge DataSets with @DBUnit(mergeDataSets = true) Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Example of merging @DataSet configurations from class and method levels. Requires mergeDataSets=true in @DBUnit. Only array properties like value and executeScriptsAfter are merged. The test verifies merged data and scripts. ```java @RunWith(JUnit4.class) @DBUnit(mergeDataSets = true) <1> @DataSet(value="yml/tweet.yml", executeScriptsAfter = "addUser.sql", executeStatementsBefore = "INSERT INTO USER VALUES (8,'user8')") public class MergeDataSetsIt { @Rule public EntityManagerProvider emProvider = EntityManagerProvider.instance("rules-it"); @Rule public DBUnitRule dbUnitRule = DBUnitRule.instance(emProvider.connection()); @Test @DataSet(value="yml/user.yml", executeScriptsAfter = "tweets.sql", executeStatementsBefore = "INSERT INTO USER VALUES (9,'user9')", strategy = SeedStrategy.INSERT) public void shouldMergeDataSetsFromClassAndMethod() { List users = em().createQuery("select u from User u").getResultList(); //2 users from user.yml plus 1 from class level 'executeStatementsBefore' and 1 user from method level 'executeStatementsBefore' assertThat(users).isNotNull().isNotEmpty().hasSize(4); User user = (User) em().createQuery("select u from User u where u.id = 9").getSingleResult(); <2> assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(9); user = (User) em().createQuery("select u from User u where u.id = 1").getSingleResult(); assertThat(user.getTweets()).isNotEmpty(); <3> assertThat(user.getTweets().get(0).getContent()).isEqualTo("dbunit rules again!"); } @AfterClass public static void afterTest() { User user = (User) em().createQuery("select u from User u where u.id = 10").getSingleResult();<4> assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(10); Tweet tweet = (Tweet) em().createQuery("select t from Tweet t where t.id = 10").getSingleResult();//scripts after assertThat(tweet).isNotNull(); assertThat(tweet.getId()).isEqualTo("10"); } } ``` -------------------------------- ### Multiple databases with @Rule and executorId Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Alternative approach to multiple databases using @Rule with explicit executor ids. Each DBUnitRule is bound to a separate EntityManagerProvider connection, and the @DataSet annotation specifies the executorId to target the correct database. The example also disables constraints during seeding. ```java @Rule public EntityManagerProvider emProvider1 = EntityManagerProvider.instance("dataset1-pu"); @Rule public EntityManagerProvider emProvider2 = EntityManagerProvider.instance("dataset2-pu"); @Rule public DBUnitRule exec1Rule = DBUnitRule.instance("exec1",emProvider1.getConnection());<1> @Rule public DBUnitRule exec2Rule = DBUnitRule.instance("exec2",emProvider2.getConnection()); @Test @DataSet(value = "datasets/yml/users.yml",disableConstraints = true, executorId = "exec1") <2> public void shouldSeedDataSetDisablingContraints() { User user = (User) emProvider1.em().createQuery("select u from User u where u.id = 1").getSingleResult(); assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(1); } @Test @DataSet(value = "datasets/yml/users.yml",disableConstraints = true, executorId = "exec2") public void shouldSeedDataSetDisablingContraints2() { User user = (User) emProvider2.em().createQuery("select u from User u where u.id = 1").getSingleResult(); assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(1); } ``` -------------------------------- ### Transactional JDBC test with @DataSet and @ExpectedDataSet Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Pure JDBC example using @DataSet(cleanBefore = true, transactional = true) and @ExpectedDataSet. Commented code (setAutoCommit, commit) is not needed because the test is transactional. Uses JUnit5 and Flyway. ```java @Test @DataSet(cleanBefore = true, transactional = true) @ExpectedDataSet(value = "usersInserted.yml") public void shouldInserUsers() throws SQLException { Connection connection = flyway.getDataSource().getConnection(); //connection.setAutoCommit(false); //transactional=true java.sql.Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); statement.addBatch("INSERT INTO User VALUES (1, 'user1')"); statement.addBatch("INSERT INTO User VALUES (2, 'user2')"); statement.addBatch("INSERT INTO User VALUES (3, 'user3')"); statement.executeBatch(); //connection.commit(); //connection.setAutoCommit(false); } ``` -------------------------------- ### Cucumber step definitions without CDI Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Cucumber step definitions without CDI, using EntityManagerProvider and DataSetExecutor to create datasets programmatically. The setUp method clears the JPA first-level cache between scenarios. The given step creates a dataset from contacts.yml and verifies the count. ```java public class ContactStepsWithoutCDI { EntityManagerProvider entityManagerProvider = EntityManagerProvider.newInstance("customerDB"); DataSetExecutor dbunitExecutor; Long count; @Before public void setUp(){ dbunitExecutor = DataSetExecutorImpl.instance(new ConnectionHolderImpl(entityManagerProvider.connection())); em().clear();//important to clear JPA first level cache between scenarios } @Given("^we have a list of contacts2$") public void given() { dbunitExecutor.createDataSet(new DataSetConfig("contacts.yml")); assertEquals(em().createQuery("select count(c.id) from Contact c").getSingleResult(), new Long(3)); } @When("^^we search contacts by name \"([^\"]*)\"2$") public void we_search_contacts_by_name_(String name) throws Throwable { Contact contact = new Contact(); contact.setName(name); Query query = em().createQuery("select count(c.id) from Contact c where UPPER(c.name) like :name"); query.setParameter("name","%"+name.toUpperCase()+"%"); count = (Long) query.getSingleResult(); } ``` -------------------------------- ### Chain EntityManagerProvider and DBUnit rules with RuleChain Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Chains the EntityManagerProvider rule before the DBUnit rule using JUnit's RuleChain, defining execution order. The EntityManagerProvider executes before the DBUnit rule in this setup. ```java EntityManagerProvider emProvider = EntityManagerProvider.instance("rules-it"); @Rule public TestRule theRule = RuleChain.outerRule(emProvider). around(DBUnitRule.instance(emProvider.connection())); ``` -------------------------------- ### Export dataset with @ExportDataSet Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Use @ExportDataSet to export the database state after test execution to a dataset file. This example exports all tables to XML at target/exported/xml/allTables.xml; XML, YML, JSON, XLS, XLSX, and CSV formats are supported. ```java @Test @DataSet("datasets/yml/users.yml") @ExportDataSet(format = DataSetFormat.XML,outputName="target/exported/xml/allTables.xml") public void shouldExportAllTablesInXMLFormat() { //data inserted inside method can be exported } ``` -------------------------------- ### Transactional test with @DataSet and @ExpectedDataSet Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Transactional test using @DataSet(transactional=true) and @ExpectedDataSet. Database Rider starts a transaction before the test and commits after test execution but before expected dataset comparison. ```java @Test @DataSet(*transactional=true*) @ExpectedDataSet(value = "yml/expectedUsers.yml",ignoreCols = "id") public void shouldMatchExpectedDataSet() { User u = new User(); u.setName("non expected user1"); User u2 = new User(); u2.setName("non expected user2"); emProvider.em().persist(u); emProvider.em().persist(u2); } ``` -------------------------------- ### Regex patterns in expected dataset Source: https://github.com/database-rider/database-rider/blob/master/README.adoc YAML dataset using regex patterns in expected values. The id uses a regex for any number, and name uses 'starts with' and 'ends with' regex patterns. ```yaml user: - id: "regex:\\d+" #any number name: regex:^expected user.* #'starts with' regex - id: "regex:\\d+" name: regex:.*user2$ #'ends with' regex ``` -------------------------------- ### Use @DBUnitInterceptor in a CDI test Source: https://github.com/database-rider/database-rider/blob/master/rider-cdi/README.adoc Example test class using the CDI interceptor. The @DBUnitInterceptor annotation activates the interceptor that seeds the database based on the @DataSet annotation. ```java @RunWith(CdiTestRunner.class) @DBUnitInterceptor <1> public class ContactServiceIt { @Inject DeltaSpikeContactService contactService; @Test @DataSet("datasets/contacts.yml") public void shouldQueryAllCompanies() { assertNotNull(contactService); assertThat(contactService.findCompanies()).hasSize(4); } } ``` -------------------------------- ### JPA entities User, Tweet, and Follower Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Defines three JPA entities (User, Tweet, Follower) with relationships and validation constraints. Used as the domain model for the database testing examples. ```java @Entity public class User { @Id @GeneratedValue private long id; private String name; @OneToMany(mappedBy = "user") private List tweets; @OneToMany(mappedBy = "followedUser") private List followers; //getters/setters } @Entity public class Tweet { @Id @GeneratedValue private String id; @Size(min = 1, max = 140) private String content; private Integer likes; @Temporal(TemporalType.TIMESTAMP) private Date date; @ManyToOne private User user; } @Entity public class Follower { @Id @GeneratedValue private long id; @JoinColumn(name = "follower_id") private User followerUser; @ManyToOne @JoinColumn(name = "user_id") private User followedUser; } ``` -------------------------------- ### Configure JDBC connection via @DBUnit annotation Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Configures a JDBC connection directly on the @DBUnit annotation, avoiding a global dbunit.yml setup. The driver class can be omitted in new JDBC drivers since version 4, and the rule instantiation no longer needs a connection. Note that @DBUnit takes precedence over the global configuration, and CDI modules ignore connection configuration. ```java @RunWith(JUnit4.class) @DBUnit(url = "jdbc:hsqldb:mem:test;DB_CLOSE_DELAY=-1", driver = "org.hsqldb.jdbcDriver", user = "sa") <1> public class ConnectionConfigIt { @Rule public DBUnitRule dbUnitRule = DBUnitRule.instance(); <2> @BeforeClass public static void initDB(){ //trigger db creation EntityManagerProvider.instance("rules-it"); } @Test @DataSet(value = "datasets/yml/user.yml") public void shouldSeedFromDeclaredConnection() { User user = (User) em().createQuery("select u from User u where u.id = 1").getSingleResult(); assertThat(user).isNotNull(); assertThat(user.getId()).isEqualTo(1); } } ``` -------------------------------- ### Cucumber feature file for contacts CRUD Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Cucumber feature file defining a scenario outline for searching contacts and a scenario for deleting a contact. The scenario outline uses an examples table with name/result pairs. The delete scenario expects the contact to be removed. ```gherkin Feature: Contacts test As a user of contacts repository I want to crud contacts So that I can expose contacts service Scenario Outline: search contacts Given we have a list of constacts When we search contacts by name "" Then we should find contacts Examples: examples1 | name | result | | delta | 1 | | sp | 2 | | querydsl | 1 | | abcd | 0 | Scenario: delete a contact Given we have a list of contacts When we delete contact by id 1 Then we should not find contact 1 ``` -------------------------------- ### Prepare Maven release with release profile Source: https://github.com/database-rider/database-rider/blob/master/release_process.txt Run this Maven command to prepare a release. It triggers GitHub Actions to deploy the release to Maven Central and publish the latest release documentation to https://database-rider.github.io/database-rider. ```bash mvn release:prepare -Prelease -Dresume=false ``` -------------------------------- ### Build native image with Gradle Source: https://github.com/database-rider/database-rider/blob/master/rider-examples/rider-micronaut/README.md Build a native image using Gradle. Requires GraalVM 19.1 or above. Run the Gradle assemble task first, then use the native-image command with the built jar. ```bash $ ./gradlew assemble $ native-image --no-server -cp build/libs/example-jpa-0.1-all.jar ``` -------------------------------- ### Build native image with Maven Source: https://github.com/database-rider/database-rider/blob/master/rider-examples/rider-micronaut/README.md Build a native image using Maven. Requires GraalVM 19.1 or above. Run the Maven package command first, then use the native-image command with the built jar. ```bash $ ./mvnw package $ native-image --no-server -cp target/example-jpa-0.1.jar ``` -------------------------------- ### Configure persistence.xml for customerDB Source: https://github.com/database-rider/database-rider/blob/master/rider-cdi/README.adoc JPA persistence unit configuration for the test database. It defines the "customerDB" persistence unit with HSQLDB in-memory settings. ```xml org.hibernate.ejb.HibernatePersistence org.example.jpadomain.Company org.example.jpadomain.Contact ``` -------------------------------- ### Custom replacer: implementation, dataset, and test Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Shows a custom replacer implementation that replaces the substring 'FOO' with 'BAR', a dataset file using 'FOO', and a test class annotated with @DBUnit(replacers = CustomReplacer.class) to enable it. ```java /** * Example implementation of Replacer which replaces string 'FOO' for 'BAR' * */ public class CustomReplacer implements Replacer { @Override public void addReplacements(ReplacementDataSet dataSet) { dataSet.addReplacementSubstring("FOO", "BAR"); } @Override public boolean equals(Object o) { if (this == o) return true; return o != null && getClass() == o.getClass(); } @Override public int hashCode() { return Objects.hash(getClass()); } } ``` ```yaml TWEET: - ID: "1" CONTENT: "FOO" USER_ID: 1 ``` ```java @DBUnit(replacers = CustomReplacer.class) <1> public class CustomReplacementIt { ``` -------------------------------- ### Expected dataset with orderBy Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Expected dataset YAML file (expectedUsersIgnoreOrder.yml) with a list of user names. Used with orderBy to ignore row ordering. ```yaml USER: - NAME: "@realpestano" - NAME: "@arhohuttunen" - NAME: "@dbunit" ``` -------------------------------- ### Cucumber step definitions with CDI and DBUnit Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Cucumber step definitions using CDI and DBUnit interceptor. The @DataSet annotation prepares the database before the given step. Step definitions must be in the same package as the runner unless glues are used. ```java package com.github.database.rider.examples.cucumber; //<1> import com.github.database.rider.api.dataset.DataSet; import cucumber.api.java.en.Given; import cucumber.api.java.en.Then; import cucumber.api.java.en.When; import org.example.jpadomain.Contact; import org.example.jpadomain.Contact_; import org.example.service.deltaspike.ContactRepository; import javax.inject.Inject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @DBUnitInterceptor // <2> public class ContactSteps { @Inject ContactRepository contactRepository; Long count; @Given("^we have a list of contacts") @DataSet("datasets/contacts.yml") //<2> public void given() { assertEquals(contactRepository.count(), new Long(3)); } @When("^^we search contacts by name \"([^\"]*)\"$") public void we_search_contacts_by_name_(String name) throws Throwable { Contact contact = new Contact(); contact.setName(name); count = contactRepository.countLike(contact, Contact_.name); } @Then("^we should find (\\d+) contacts$") public void we_should_find_result_contacts(Long result) throws Throwable { assertEquals(result,count); } @When("^we delete contact by id (\\d+)$") public void we_delete_contact_by_id(long id) throws Throwable { contactRepository.remove(contactRepository.findBy(id)); } @Then("^we should not find contact (\\d+)$") public void we_should_not_find_contacts_in_database(long id) throws Throwable { assertNull(contactRepository.findBy(id)); } } ``` -------------------------------- ### CDI beans.xml to enable DBUnitInterceptor Source: https://github.com/database-rider/database-rider/blob/master/README.adoc CDI beans.xml configuration to enable the DBUnit interceptor. Place it in src/test/resources/META-INF/beans.xml. ```xml com.github.database.rider.cdi.DBUnitInterceptorImpl ``` -------------------------------- ### Enable IncludeReplacer globally via dbunit.yml Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Global dbunit.yml configuration to enable the include replacer for all tests. Sets replacers to IncludeReplacer and also configures other properties like batchedStatements and qualifiedTableNames. ```yaml cacheConnection: false cacheTableNames: false leakHunter: true properties: batchedStatements: true qualifiedTableNames: true schema: replacers: [!!com.github.database.rider.core.replacers.IncludeReplacer {}] ``` -------------------------------- ### Test with Prolog compare operation Source: https://github.com/database-rider/database-rider/blob/master/README.adoc JUnit test using @ExpectedDataSet with compareOperation = CompareOperation.PROLOG. The test method is empty; it relies on the dataset and expected dataset to perform the assertion. ```java @Test @DataSet(value = "yml/users.yml", transactional = true) @ExpectedDataSet(value = "yml/expectedUserWithProlog.yml", compareOperation = CompareOperation.PROLOG) public void shouldSupportPrologCompareOperation() { } ``` -------------------------------- ### DataSetBuilder with defaultValue and table columns Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Builds a dataset programmatically with default values for columns. Use when you need to seed data with many rows and few columns; the builder allows setting defaults per table and using null to trigger the default value. ```java builder.defaultValue("id", -1) .table("user") .columns("id", "name") .values(1, "@dbrider") .values(2, "@dbunit") .values(null, "@dbunit3")//will use default value .table("tweet") .defaultValue("likes", 99) .columns("id", "content", "date") .values("abcdef12345", "dbunit rules!", "[DAY,NOW]") .table("follower") .columns("id", "user_id", "follower_id") .values(1, 1, 2) .build(); ``` -------------------------------- ### Test class with @DBUnitInterceptor and @DataSet Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Test class using @DBUnitInterceptor to configure datasets before tests. The test class must be a CDI bean to be intercepted. Uses @DataSet to load a YAML dataset. ```java @RunWith(CdiTestRunner.class) @DBUnitInterceptor public class DeltaspikeUsingInterceptorIt { @Inject DeltaSpikeContactService contactService; @Test @DataSet("datasets/contacts.yml") public void shouldQueryAllCompanies() { assertNotNull(contactService); assertThat(contactService.findCompanies()).hasSize(4); } } ``` -------------------------------- ### Produce EntityManager for CDI tests Source: https://github.com/database-rider/database-rider/blob/master/rider-cdi/README.adoc Entity manager producer for tests. It extends CdiConfig and produces an EntityManager from the "customerDB" persistence unit. ```java @Specializes @ApplicationScoped public class CdiTestConfig extends CdiConfig { <1> private EntityManager em; @Produces public EntityManager produce(){ synchronized (this){ return EntityManagerProvider.instance("customerDB").em(); } } } ``` -------------------------------- ### Configure DBUnit via @DBUnit annotation Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Configures DBUnit via the @DBUnit annotation at method level. The annotation takes precedence over the dbunit.yml global configuration. ```java @Test @DBUnit(cacheConnection = true, cacheTableNames = false, allowEmptyFields = true,batchSize = 50) public void shouldLoadDBUnitConfigViaAnnotation() { } ``` -------------------------------- ### YAML dataset for users, tweets, and followers Source: https://github.com/database-rider/database-rider/blob/master/README.adoc A DBUnit YAML dataset defining sample data for the User, Tweet, and Follower tables. Used to prepare the database before test execution. ```yaml user: - id: 1 name: "@realpestano" - id: 2 name: "@dbunit" tweet: - id: abcdef12345 content: "dbunit rules!" user_id: 1 follower: - id: 1 user_id: 1 follower_id: 2 ``` -------------------------------- ### Export YML DataSet Programmatically with DataSetExporter Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Programmatic export using DataSetExporter.getInstance().export() with a DataSetExportConfig that sets the output file name. The test inserts a user, exports to target/user.yml, and asserts the file exists and contains the expected YAML content. ```java @Test @DataSet(cleanBefore=true) public void shouldExportYMLDataSetWithoutAnnotations() throws SQLException, DatabaseUnitException{ tx().begin(); User u1 = new User(); u1.setName("u1"); em().persist(u1);//just insert a user and assert it is present in exported dataset tx().commit(); DataSetExporter.getInstance().export(emProvider.connection(), new DataSetExportConfig().outputFileName("target/user.yml")); File ymlDataSet = new File("target/user.yml"); assertThat(ymlDataSet).exists(); assertThat(contentOf(ymlDataSet)). contains("USER:"+NEW_LINE + " - ID: 1"+NEW_LINE + " NAME: \"u1\""+NEW_LINE); } ``` -------------------------------- ### DataSetProvider with DataSetBuilder and generated dataset Source: https://github.com/database-rider/database-rider/blob/master/README.adoc DataSetProvider implementation using DataSetBuilder to define a dataset programmatically, and the generated YAML dataset it produces. The builder uses default values, table/column/row methods, and supports adding rows to existing tables. ```java public class UserDataSetProvider implements DataSetProvider { @Override public IDataSet provide() throws DataSetException { DataSetBuilder builder = new DataSetBuilder(); IDataSet dataSet = builder .defaultValue("id", -1) //default value for all tables that don't provide a value for 'id' column .table("USER") //start adding rows to 'USER' table .column("ID",1) .column(name,"@realpestano") .row() //keeps adding rows to the current table .column(id,2) .column("NAME","@dbunit") .table("TWEET") //starts adding rows to 'TWEET' table .defaultValue("LIKES", 99) //default value only for table tweet, the value will be used if column is not specified .column("ID","abcdef12345") .column("CONTENT","dbunit rules!") .column("DATE","[DAY,NOW]") .table("FOLLOWER").column(id,1) .column("USER_ID",1) .column("FOLLOWER_ID",2) .table("USER")// we still can add rows to table already added .column(name,"@new row") .build(); return dataSet; } } ``` ```yaml FOLLOWER: - ID: 1 USER_ID: 1 FOLLOWER_ID: 2 TWEET: - ID: "abcdef12345" CONTENT: "dbunit rules!" DATE: "2019-05-14 19:26:56.0" LIKES: 99 USER: - ID: 1 NAME: "@dbunit" - ID: 2 NAME: "@dbrider" - ID: -1 NAME: "@new row" ``` -------------------------------- ### Date replacer: dataset and test Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Shows a dataset file using the [DAY,NOW] placeholder and a JUnit test that replaces it with the current date. The test disables constraints to allow a TWEET with an inexistent USER_ID. ```yaml TWEET: - ID: "1" CONTENT: "dbunit rules!" DATE: "[DAY,NOW]" USER_ID: 1 ``` ```java @Before public void setup(){ now = Calendar.getInstance(); } @Test @DataSet(value = "date-replacements.yml",disableConstraints = true) //disabled constraints so we can have a TWEET with inexistent USER_ID public void shouldReplaceDateWithNowPlaceHolder() { Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery("select t from Tweet t where t.id = '1'").getSingleResult(); assertThat(tweet).isNotNull(); assertThat(tweet.getDate().get(Calendar.DAY_OF_MONTH)).isEqualTo(now.get(Calendar.DAY_OF_MONTH)); assertThat(tweet.getDate().get(Calendar.HOUR_OF_DAY)).isEqualTo(now.get(Calendar.HOUR_OF_DAY)); } ``` -------------------------------- ### Add Maven Snapshot Repository to pom.xml Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Maven repository configuration to use snapshot versions from the Sonatype snapshots repository. Add this snippet to your pom.xml to access snapshot releases. ```xml snapshots libs-snapshot https://oss.sonatype.org/content/repositories/snapshots ``` -------------------------------- ### Include replacer: file, dataset, and test Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Shows the include replacer: a file (doc.xml) whose content is included into a dataset column using the [INCLUDE] prefix. The test enables the replacer via @DataSet(replacers = IncludeReplacer.class) and asserts the included content. ```xml Anything in this file will be included into the column with [INCLUDE] replacement! ``` ```yaml TWEET: - ID: "1" CONTENT: "[INCLUDE]datasets/xml/doc.xml" ``` ```java @Test @DataSet(replacers = IncludeReplacer.class, value = "datasets/yml/include-xml-replacements.yml") public void shouldReplaceXmlFileContent() { Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery("select t from Tweet t where t.id = '1'").getSingleResult(); assertThat(tweet).isNotNull(); assertThat(tweet.getContent()).contains("" + NEW_LINE + "Anything in this file will be included into the column with [INCLUDE] replacement!"); } ``` -------------------------------- ### Initial dataset for CONTAINS test Source: https://github.com/database-rider/database-rider/blob/master/README.adoc YAML dataset (users.yml) with two user rows. Used as the initial dataset for the CONTAINS test. ```yaml USER: - ID: 1 NAME: "@realpestano" - ID: 2 NAME: "@dbunit" ``` -------------------------------- ### Use DataSetProvider in @DataSet annotation Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Uses a DataSetProvider class in the @DataSet annotation to seed the database programmatically. The provider is referenced by its class and cleanBefore is set to true. The test then queries and asserts the seeded data. ```java @Test @DataSet(provider = UserDataSetProvider.class, cleanBefore = true) public void shouldSeedDatabaseProgrammatically() { List users = EntityManagerProvider.em().createQuery("select u from User u ").getResultList(); assertThat(users). isNotNull(). isNotEmpty().hasSize(3). extracting("name"). contains("@dbunit", "@dbrider", "@new row"); } ``` -------------------------------- ### Groovy dependency for scriptable datasets Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Maven dependency required for Groovy scripting in datasets. Add this to the classpath to use groovy: prefix in dataset columns. ```xml org.codehaus.groovy groovy-all 2.4.6 test ``` -------------------------------- ### JUnit 5 test with DBUnitExtension Source: https://github.com/database-rider/database-rider/blob/master/README.adoc JUnit 5 test using the DBUnit extension. The extension obtains the JDBC connection by reflection, so you must declare a field or method with `ConnectionHolder` as the return type. ```java @ExtendWith(DBUnitExtension.class) @RunWith(JUnitPlatform.class) public class DBUnitJUnit5Test { private ConnectionHolder connectionHolder = () -> instance("junit5-pu").connection(); <1> @BeforeAll @DataSet("empty.yml") public static void setUp() { } @BeforeEach @DataSet("users.yml") public static void setUp() { } @Test @DataSet(value = "usersWithTweet.yml") public void shouldListUsers() { List users = em().createQuery("select u from User u").getResultList(); assertThat(users).isNotNull().isNotEmpty().hasSize(2); } ``` -------------------------------- ### Register DBUnitInterceptorImpl in beans.xml Source: https://github.com/database-rider/database-rider/blob/master/rider-cdi/README.adoc Register the DBUnitInterceptorImpl interceptor in your test beans.xml. This is required for the CDI interceptor to work. ```xml com.github.database.rider.cdi.DBUnitInterceptorImpl ``` -------------------------------- ### Prolog assertions expected dataset Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Expected dataset using Prolog assertions with variable $$x$$ linking ID and USER_ID values. Used with compareOperation = CompareOperation.PROLOG. ```yaml USER: - ID: $$x$$ NAME: "@realpestano" TWEET: - ID: abcdef12345 CONTENT: "dbunit rules!" USER_ID: $$x$$ ``` -------------------------------- ### Leak hunter with @DBUnit(leakHunter = true) Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Enable leak hunter by setting leakHunter = true in @DBUnit. The test expects LeakHunterException with a message indicating the number of open connections left after execution; setting leakHunter = false disables the check. ```java @RunWith(JUnit4.class) @DBUnit(leakHunter = true) public class LeakHunterIt { @Rule public DBUnitRule dbUnitRule = DBUnitRule.instance(new ConnectionHolderImpl(getConnection())); @Rule public ExpectedException exception = ExpectedException.none(); @Test @DataSet("yml/user.yml") public void shouldFindConnectionLeak() { exception.expect(LeakHunterException.class); <1> exception.expectMessage("Execution of method shouldFindConnectionLeak left 1 open connection(s)."); createLeak(); } @Test @DataSet("yml/user.yml") public void shouldFindTwoConnectionLeaks() { exception.expect(LeakHunterException.class); exception.expectMessage("Execution of method shouldFindTwoConnectionLeaks left 2 open connection(s)."); createLeak(); createLeak(); } @Test @DataSet("yml/user.yml") @DBUnit(leakHunter = false) public void shouldNotFindConnectionLeakWhenHunterIsDisabled() { createLeak(); } } ``` -------------------------------- ### Null replacer: dataset and test Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Shows a dataset file using the [null] placeholder and a JUnit test that replaces it with null. The test also verifies that a literal "null" string is not replaced. ```yaml TWEET: - ID: "1" CONTENT: "[null]" USER_ID: 1 - ID: "2" CONTENT: "null" USER_ID: 1 ``` ```java @Test @DataSet(value = "null-replacements.yml", disableConstraints = true) public void shouldReplaceNullPlaceholder() { Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery("select t from Tweet t where t.id = '1'").getSingleResult(); assertThat(tweet).isNotNull(); assertThat(tweet.getContent()).isNull(); Tweet tweet2 = (Tweet) EntityManagerProvider.em().createQuery("select t from Tweet t where t.id = '2'").getSingleResult(); assertThat(tweet2).isNotNull(); assertThat(tweet2.getContent()).isNotNull().isEqualTo("null"); } ``` -------------------------------- ### dbunit.yml global config with custom replacer Source: https://github.com/database-rider/database-rider/blob/master/README.adoc Global dbunit-config.yml configuration to register a custom replacer for all tests. The replacers property lists the CustomReplacer class. ```yaml cacheConnection: false cacheTableNames: false leakHunter: true properties: batchedStatements: true qualifiedTableNames: true schema: public batchSize: 200 fetchSize: 200 allowEmptyFields: true escapePattern: "[?]" datatypeFactory: !!com.github.database.rider.core.configuration.DBUnitConfigTest$MockDataTypeFactory {} replacers: [!!com.github.database.rider.core.replacers.CustomReplacer {}] ```