{"id":13498824,"url":"https://github.com/database-rider/database-rider","last_synced_at":"2026-01-28T17:01:02.563Z","repository":{"id":38422332,"uuid":"68379040","full_name":"database-rider/database-rider","owner":"database-rider","description":"Database testing made easy!","archived":false,"fork":false,"pushed_at":"2024-10-27T20:10:00.000Z","size":18203,"stargazers_count":663,"open_issues_count":74,"forks_count":136,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-03T20:05:49.921Z","etag":null,"topics":["cdi","db-testing","dbrider","dbunit","deltaspike","jpa","junit5","micronautfw","quarkus","spring","springboot"],"latest_commit_sha":null,"homepage":"https://database-rider.github.io/database-rider","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/database-rider.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.adoc","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-16T12:47:36.000Z","updated_at":"2025-04-01T22:46:57.000Z","dependencies_parsed_at":"2024-02-12T20:26:34.936Z","dependency_job_id":"63810ee7-df3e-4b2d-a42a-174e5e86883c","html_url":"https://github.com/database-rider/database-rider","commit_stats":{"total_commits":940,"total_committers":67,"mean_commits":"14.029850746268657","dds":0.6659574468085107,"last_synced_commit":"67d43636143b54c4c3c5b5afcd302e92c2332eab"},"previous_names":[],"tags_count":84,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/database-rider%2Fdatabase-rider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/database-rider%2Fdatabase-rider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/database-rider%2Fdatabase-rider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/database-rider%2Fdatabase-rider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/database-rider","download_url":"https://codeload.github.com/database-rider/database-rider/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248335718,"owners_count":21086644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cdi","db-testing","dbrider","dbunit","deltaspike","jpa","junit5","micronautfw","quarkus","spring","springboot"],"created_at":"2024-07-31T21:00:45.083Z","updated_at":"2026-01-28T17:01:02.526Z","avatar_url":"https://github.com/database-rider.png","language":"Java","funding_links":[],"categories":["Testing","测试"],"sub_categories":[],"readme":"= Database Rider\n:page-layout: base\n:source-language: java\n:icons: font\n:linkattrs:\n:sectanchors:\n:sectlink:\n:numbered:\n:doctype: book\n:toc: preamble\n:tip-caption: :bulb:\n:note-caption: :information_source:\n:important-caption: :heavy_exclamation_mark:\n:caution-caption: :fire:\n:warning-caption: :warning:\n\n++++\n\u003ca href=\"https://s22.postimg.org/t6k9n4mmp/rider_logo.png\"\u003e\n\u003cimg align=\"right\" height=\"400\" width=\"300\" src=\"https://github.com/database-rider/database-rider/raw/gh-pages/images/rider_orochi.png\" style=\"max-width:100%;\"\u003e\n\u003c/a\u003e\n++++\n\n[quote]\n____\nSo you can ride the database in your JUnit tests!\n____\n\n\nimage:https://github.com/database-rider/database-rider/actions/workflows/ci.yml/badge.svg[Build Status, link=https://github.com/database-rider/database-rider/actions/workflows/ci.yml]\nimage:https://coveralls.io/repos/database-rider/database-rider/badge.png[Coverage, link=https://coveralls.io/r/database-rider/database-rider]\nimage:https://img.shields.io/maven-central/v/com.github.database-rider/rider-core.svg?label=Maven%20Central[\"Maven Central\",link=\"https://search.maven.org/search?q=g:com.github.database-rider\"]\nimage:https://sonarcloud.io/api/project_badges/measure?project=com.github.database-rider:rider-parent\u0026metric=alert_status[\"Sonar\", link=\"https://sonarcloud.io/dashboard?id=com.github.database-rider%3Arider-parent\"]\nimage:https://badges.gitter.im/database-rider/community.svg[\"Gitter\", link=\"https://gitter.im/database-rider/community?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\"]\n\nThis project aims for bringing http://dbunit.sourceforge.net/[DBUnit] closer to your JUnit tests *so database testing will feel like a breeze!*\n\nWatch https://www.youtube.com/watch?v=A5ryED3a8FY[1.0 promo video^] to get an idea.\n\nA lot of this work is based on https://github.com/arquillian/arquillian-extension-persistence/[Arquillian persistence extension] and focus on simplicity (one dependency - dbunit).\n\n\n== Introduction\n\nConsider the following (jpa) entities:\n\n[source, java]\n----\n@Entity\npublic class User {\n\n    @Id\n    @GeneratedValue\n    private long id;\n\n    private String name;\n\n    @OneToMany(mappedBy = \"user\")\n    private List\u003cTweet\u003e tweets;\n\n    @OneToMany(mappedBy = \"followedUser\")\n    private List\u003cFollower\u003e followers;\n\n    //getters/setters\n\n }\n\n@Entity\npublic class Tweet {\n\n    @Id\n    @GeneratedValue\n    private String id;\n\n    @Size(min = 1, max = 140)\n    private String content;\n\n    private Integer likes;\n\n    @Temporal(TemporalType.TIMESTAMP)\n    private Date date;\n\n    @ManyToOne\n    private User user;\n}\n\n@Entity\npublic class Follower {\n\n    @Id\n    @GeneratedValue\n    private long id;\n\n    @JoinColumn(name = \"follower_id\")\n    private User followerUser;\n\n\n    @ManyToOne\n    @JoinColumn(name = \"user_id\")\n    private User followedUser;\n\n}\n\n----\n\nand the following dbunit yaml dataset:\n\n.src/test/resources/datasets/users.yml\n----\nuser:\n  - id: 1\n    name: \"@realpestano\"\n  - id: 2\n    name: \"@dbunit\"\ntweet:\n  - id: abcdef12345\n    content: \"dbunit rules!\"\n    user_id: 1\nfollower:\n  - id: 1\n    user_id: 1\n    follower_id: 2\n----\n\nYou should be able to prepare your database before test execution, like below:\n\n[source,java]\n----\n@RunWith(JUnit4.class)\npublic class UserIt {\n\n   @Rule\n   public EntityManagerProvider emProvider = EntityManagerProvider.instance(\"rules-it\");\n\n   @Rule\n   public DBUnitRule dbUnitRule = DBUnitRule.instance(emProvider.connection());\n\n   @Test\n   @DataSet(value = \"datasets/yml/users.yml\")\n   public void shouldLoadUserFollowers() {\n        User user = (User) emProvider.em().createQuery(\"select u from User u left join fetch u.followers where u.id = 1\").getSingleResult();\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isEqualTo(1);\n        assertThat(user.getTweets()).hasSize(1);\n        assertEquals(user.getTweets().get(0).getContent(), \"dbunit rules!\");\n        assertThat(user.getFollowers()).isNotNull().hasSize(1);\n        Follower expectedFollower = new Follower(2,1);\n        assertThat(user.getFollowers()).contains(expectedFollower);\n   }\n----\n\nNOTE: \u003c\u003cEntityManagerProvider\u003e\u003e is a simple JUnit rule that creates a JPA entityManager (and caches it) for each test. DBunit rule don't depend on EntityManagerProvider, it only needs a *JDBC connection*;\n\n\n== Documentation\n\nA getting started guide can be found here http://database-rider.github.io/getting-started/.\n\nFor main features overview see http://database-rider.github.io/database-rider/latest/documentation.html[project living documentation^].\n\nOlder documentation versions can be found here: https://database-rider.github.io/database-rider/#documentation.\n\n\n== Rider Core\n\nThis module is the basis for subsequent modules. It contains a JUnit rule (shown above), the api for dataset, DBunit configuration and *DataSetExecutor* which is responsible for dataset creation.\n\n=== Adding Database Rider core to your project\n\n\n[source, xml]\n----\n\u003cdependency\u003e\n      \u003cgroupId\u003ecom.github.database-rider\u003c/groupId\u003e\n      \u003cartifactId\u003erider-core\u003c/artifactId\u003e\n      \u003cversion\u003e1.44.0\u003c/version\u003e\n      \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n----\n\nTIP: Use `jakarta` maven classifier if you use jakarta-cdi or jakarta-persistence\n\n\n[NOTE]\n====\nIt will bring the following (transitive) dependencies to your test classpath:\n\n[source,xml]\n----\n\u003cdependency\u003e\n      \u003cgroupId\u003eorg.dbunit\u003c/groupId\u003e\n      \u003cartifactId\u003edbunit\u003c/artifactId\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n      \u003cgroupId\u003eorg.yaml\u003c/groupId\u003e\n      \u003cartifactId\u003esnakeyaml\u003c/artifactId\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n      \u003cgroupId\u003eorg.codehaus.jackson\u003c/groupId\u003e\n      \u003cartifactId\u003ejackson-mapper-lgpl\u003c/artifactId\u003e\n\u003c/dependency\u003e\n----\n====\n\n=== DataSet executor\nA DataSet executor is a component which creates DBUnit datasets. Datasets are \"sets\" of data (tables and rows) that represent the *state of the database*. DataSets are defined as textual files in *YAML*, *XML*, *JSON*, *CSV*, *XLS* or *XLSX* format, https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/resources/datasets/[see examples here^].\n\nAs in DBUnit Rule, `dataset executor` just needs a JDBC connection to be instantiated:\n\n\n[source,java]\n----\nimport static com.github.database.rider.util.EntityManagerProvider.em;\nimport static com.github.database.rider.util.EntityManagerProvider.instance;\n\n@RunWith(JUnit4.class)\npublic class DataSetExecutorIt {\n\n    public EntityManagerProvider emProvider = instance(\"executor-it\");\n\n    private static DataSetExecutorImpl executor;\n\n    @BeforeClass\n    public static void setup() {\n        executor = DataSetExecutorImpl.instance(new ConnectionHolderImpl(emProvider.getConnection()));\n    }\n\n    @Test\n    public void shouldSeedUserDataSetUsingExecutor() {\n         DataSetConfig dataSetConfig = new DataSetConfig(\"datasets/yml/users.yml\");\u003c1\u003e\n         executor.createDataSet(dataSetConfig);\u003c2\u003e\n         User user = (User) em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n         assertThat(user).isNotNull();\n         assertThat(user.getId()).isEqualTo(1);\n      }\n}\n----\n\u003c1\u003e As we are not using @Rule, which is responsible for reading @DataSet annotation, we have to provide *DataSetConfig* so executor can create the dataset.\n\u003c2\u003e this is done implicitly by *@Rule DBUnitRule*.\n\nDataSet executor setup and logic is `hidden` by DBUnit @Rule and @DataSet annotation.\n\n[IMPORTANT]\n====\nSince `v1.13.0` you can use \u003c\u003cRiderDSL\u003e\u003e which provides a fluent api as an alternative to DataSetExecutor (and `@DataSet`):\n\n[source,java]\n----\nimport static com.github.database.rider.util.EntityManagerProvider.em;\nimport static com.github.database.rider.util.EntityManagerProvider.instance;\n\n@RunWith(JUnit4.class)\npublic class DataSetExecutorIt {\n\n    public EntityManagerProvider emProvider = instance(\"executor-it\");\n\n    @Test\n    public void shouldSeedUserDataSetUsingRiderDSL() {\n         RiderDSL.withConnection(emProvider.getConnection())\n                 .withDataSetConfig(new DataSetConfig(\"datasets/yml/users.yml\")\n                                   .cleanBefore(true))\n                 .withDBUnitConfig(new DBUnitConfig()\n                                   .addDBUnitProperty(\"caseSensitiveTableNames\", false))\n                 .createDataSet();\n         User user = (User) em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n         assertThat(user).isNotNull();\n         assertThat(user.getId()).isEqualTo(1);\n      }\n}\n----\n\n====\n\n=== Configuration\n\nThere are two types of configuration in Database Rider: `DataSet` and `DBUnit`.\n\n==== DataSet Configuration\n\nThis basically setup the `dataset` which will be used. The only way to configure a dataset is using *@DataSet* annotation.\n\nIt can be used at *class* or *method* level:\n\n[source,java]\n----\n     @Test\n     @DataSet(value =\"users.yml\", strategy = SeedStrategy.UPDATE,\n            disableConstraints = true,cleanAfter = true,transactional = true)\n     public void shouldLoadDataSetConfigFromAnnotation(){\n\n      }\n----\n\nHere are possible values:\n\n[cols=\"3*\", options=\"header\"]\n|===\n|Name | Description | Default\n|value\na|Dataset file name using\n\n* test resources folder as root directory.\n** eg. 'yml/users.yml'\n* URL-Notation for registered stream-handlers\n** eg. 'file:///C:/dir/users.xml', 'http://...')\n** except: loading csv datasets is only supported by the file-protocol\n\nMultiple, comma separated, dataset file names can be provided.| \"\"\n|executorId| Name of dataset executor for the given dataset.| DataSetExecutorImpl.DEFAULT_EXECUTOR_ID\n|strategy| DataSet seed strategy. Possible values are: CLEAN_INSERT, INSERT, REFRESH and UPDATE.| CLEAN_INSERT, meaning that DBUnit will clean and then insert data in tables present on provided dataset.\n|useSequenceFiltering| If true dbunit will look at constraints and dataset to try to determine the correct ordering for the SQL statements.| true\n|tableOrdering| A list of table names used to reorder DELETE operations to prevent failures due to circular dependencies.| \"\"\n|disableConstraints| Disable database constraints.| false\n|cleanBefore| If true Database Rider will try to delete database before test in a smart way by using table ordering and brute force.| false\n|cleanAfter| If true Database Rider will try to delete database after test in a smart way by using table ordering and brute force.| false\n|transactional| If true a transaction will be started before test and committed after test execution. | false\n|executeStatementsBefore| A list of jdbc statements to execute before test.| {}\n|executeStatementsAfter| A list of jdbc statements to execute after test.| {}\n|executeScriptsBefore| A list of sql script files to execute before test. Note that commands inside sql file must be separated by `;`.| {}\n|executeScriptsAfter| A list of sql script files to execute after test. Note that commands inside sql file must be separated by `;`.| {}\n|skipCleaningFor| Allows user to provide tables which will NOT be cleaned in `cleanBefore` and `cleanAfter`.| {}\n|replacers| Implementations of `com.github.database.rider.core.replacers.Replacer` to be used as dataset replacement during seeding database.| {}\n|===\n\n==== DBUnit Configuration\n\nThis basically setup `DBUnit` itself. It can be configured by *@DBUnit* annotation (class or method level) and *dbunit.yml* file present in test resources folder.\n\n[source,java]\n----\n    @Test\n    @DBUnit(cacheConnection = true, cacheTableNames = false, allowEmptyFields = true,batchSize = 50)\n    public void shouldLoadDBUnitConfigViaAnnotation() {\n\n    }\n----\n\nHere is a dbunit.yml example, also the default values:\n\n.src/test/resources/dbunit.yml\n----\ncacheConnection: true\ncacheTableNames: true\nleakHunter: false\nmergeDataSets: false\nmergingStrategy: METHOD \u003c1\u003e\ncaseInsensitiveStrategy: UPPERCASE \u003c2\u003e\nraiseExceptionOnCleanUp: false \u003c3\u003e\nexpectedDbType: UNKNOWN \u003c4\u003e\ndisableSequenceFiltering: false \u003c5\u003e\ndisablePKCheckFor: [\"\"] \u003c6\u003e\nalwaysCleanBefore: false \u003c7\u003e\nalwaysCleanAfter: false \u003c8\u003e\nproperties:\n  batchedStatements:  false\n  qualifiedTableNames: false\n  schema: null\n  caseSensitiveTableNames: false\n  batchSize: 100\n  fetchSize: 100\n  allowEmptyFields: false\n  escapePattern: \u003c9\u003e\n  datatypeFactory: !!com.github.database.rider.core.configuration.DBUnitConfigTest$MockDataTypeFactory {} \u003c10\u003e\n  tableType: [\"TABLE\"]\nconnectionConfig:\n  driver: \"\"\n  url: \"\"\n  user: \"\"\n  password: \"\"\n----\n\u003c1\u003e Strategy for merging datasets, if `METHOD` then the method level dataset will be loaded first but if `CLASS` then the class level dataset will be loaded first.\n\u003c2\u003e Only applied when `caseSensitiveTableNames` is `false`. Valid values are `UPPERCASE` and `LOWERCASE`.\n\u003c3\u003e If enabled an exception will be raised when `cleanBefore` or `cleanAfter` fails. If disabled then only a warn message is logged. Default is false.\n\u003c4\u003e In the process of initialization, if the actual database type is different from the expected database type, exception will be thrown unless the expected database type is UNKNOWN. Default is UNKNOWN.\n\u003c5\u003e Disables sequenceFiltering at dbunit level, overriding the default behavior of `@DataSet(useSequenceFiltering)` which is true.\n\u003c6\u003e List of table names to disable primary key checking while seeding the database.\n\u003c7\u003e Always enables cleanBefore at dbunit level, overriding the default behavior of `@DataSet(cleanBefore)` which is\nfalse.\n\u003c8\u003e Always enables cleanAfter at dbunit level, overriding the default behavior of `@DataSet(cleanAfter)` which is false.\n\u003c9\u003e Make it possible to define a datatype factory, https://github.com/database-rider/database-rider/issues/30[see\nissue #30^] for details.\n\u003c10\u003e Allows to configure DBUnit escapePattern property. Note that since v`1.28.0` DBRider will discover the\nescapePattern for each DB without the need to use the escapePattern property in @DBUnit or via dbunit.yml config file. If an espapePattern is provided then it will be used.\n\nIMPORTANT: `@DBUnit` annotation takes precedence over `dbunit.yml` global configuration which will be used only if the annotation is not present.\n\nTIP: `System properties` and `Environment variables` can be used to resolve properties of type *String*. The value of the property must follow the format: `${system property or env var name}`. Check both annotation and global file https://github.com/database-rider/database-rider/blob/be436283070f95f3487f9f41e7b773da23222eb4/rider-core/src/test/java/com/github/database/rider/core/configuration/DBUnitConfigTest.java#L175-L225[example here^].\n\n\n=== JDBC Connection\n\nAs seen in examples above `DBUnit` needs a JDBC connection to be instantiated. To avoid creating connection for each test you can define it in *dbunit.yml* for all tests or define in *@DBUnit* on each test.\n\nNOTE: `@DBUnit` annotation takes precedence over dbunit.yml global configuration.\n\n==== Example\n\n[source, java, linenums]\n----\n@RunWith(JUnit4.class)\n@DBUnit(url = \"jdbc:hsqldb:mem:test;DB_CLOSE_DELAY=-1\", driver = \"org.hsqldb.jdbcDriver\", user = \"sa\") \u003c1\u003e\npublic class ConnectionConfigIt {\n\n    @Rule\n    public DBUnitRule dbUnitRule = DBUnitRule.instance(); \u003c2\u003e\n\n\n\n    @BeforeClass\n    public static void initDB(){\n        //trigger db creation\n        EntityManagerProvider.instance(\"rules-it\");\n    }\n\n    @Test\n    @DataSet(value = \"datasets/yml/user.yml\")\n    public void shouldSeedFromDeclaredConnection() {\n        User user = (User) em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isEqualTo(1);\n    }\n}\n----\n\u003c1\u003e driver class can be ommited in new JDBC drivers since version 4.\n\u003c2\u003e Note that the rule instantiation doesn't need a connection anymore.\n\nIMPORTANT: As CDI module depends on a produced entity manager, connection configuration will be ignored.\n\n=== Rule chaining\n\nDBUnit Rule can be https://github.com/junit-team/junit4/wiki/rules#rulechain[chained with other rules^] so you can define execution order among rules.\n\nIn example below \u003c\u003cEntityManagerProvider rule\u003e\u003e executes *before* `DBUnit rule`:\n\n[source,java,linenums]\n----\n EntityManagerProvider emProvider = EntityManagerProvider.instance(\"rules-it\");\n\n   @Rule\n   public TestRule theRule = RuleChain.outerRule(emProvider).\n            around(DBUnitRule.instance(emProvider.connection()));\n----\n\n=== Multiple Databases\nEach executor has a JDBC connection so multiple databases can be handled by using multiple dataset executors:\n\n[source, java]\n----\nimport static com.github.database.rider.util.EntityManagerProvider.instance;\n\n@RunWith(JUnit4.class)\npublic class MultipleExecutorsIt {\n\n\n    private static List\u003cDataSetExecutorImpl\u003e executors = new ArrayList\u003c\u003e;\n\n    @BeforeClass\n    public static void setup() { \u003c1\u003e\n        executors.add(DataSetExecutorImpl.instance(\"executor1\", new ConnectionHolderImpl(instance(\"executor1-pu\").getConnection())));\n        executors.add(DataSetExecutorImpl.instance(\"executor2\", new ConnectionHolderImpl(instance(\"executor2-pu\").getConnection())));\n    }\n\n    @Test\n    public void shouldSeedUserDataSet() {\n         for (DataSetExecutorImpl executor : executors) {\n             DataSetConfig dataSetConfig = new DataSetConfig(\"datasets/yml/users.yml\");\n             executor.createDataSet(dataSetConfig);\n                User user = (User) EntityManagerProvider.instance(executor.getId() + \"-pu\").em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n                assertThat(user).isNotNull();\n                assertThat(user.getId()).isEqualTo(1);\n            }\n        }\n\n}\n\n----\n\u003c1\u003e As you can see each executor is responsible for a database, in case a JPA persistence unit\n\n\nAlso note that the same can be done using @Rule but pay attention that you must provide executor id in *@DataSet annotation*.\n\n[source, java]\n----\n    @Rule\n    public EntityManagerProvider emProvider1 = EntityManagerProvider.instance(\"dataset1-pu\");\n\n    @Rule\n    public EntityManagerProvider emProvider2 = EntityManagerProvider.instance(\"dataset2-pu\");\n\n    @Rule\n    public DBUnitRule exec1Rule = DBUnitRule.instance(\"exec1\",emProvider1.getConnection());\u003c1\u003e\n\n    @Rule\n    public DBUnitRule exec2Rule = DBUnitRule.instance(\"exec2\",emProvider2.getConnection());\n\n    @Test\n    @DataSet(value = \"datasets/yml/users.yml\",disableConstraints = true, executorId = \"exec1\") \u003c2\u003e\n    public void shouldSeedDataSetDisablingContraints() {\n        User user = (User) emProvider1.em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isEqualTo(1);\n     }\n\n    @Test\n    @DataSet(value = \"datasets/yml/users.yml\",disableConstraints = true, executorId = \"exec2\")\n    public void shouldSeedDataSetDisablingContraints2() {\n        User user = (User) emProvider2.em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isEqualTo(1);\n     }\n----\n\n\u003c1\u003e *exec1* is the id of executor responsible for dataset1-pu\n\u003c2\u003e executorId must match id provided in @Rule annotation\n\n==== Multiple databases in Spring tests\n\nSince `v1.9.0` both `Rider Spring` and `Rider JUnit 5` with `SpringBoot` support multiple datasources. You just need to specify the *dataSourceBeanName* property in `@DBRider` annotation:\n\n[source, java]\n----\n@DBRider //default datasource is used\n@SpringBootTest\npublic class MultipleDataSourcesTest {\n\n    @Autowired\n    private UserRepository userRepository; //from user datasource\n\n    @Autowired\n    private CompanyRepository companyRepository; //from company datasource\n\n\n    @Test\n    @DataSet(\"users.yml\")\n    public void shouldListUsers() {\n        assertThat(userRepository.count()).isEqualTo(3);\n        assertThat(userRepository.findByEmail(\"springboot@gmail.com\")).isEqualTo(new User(3));\n    }\n\n    @Test\n    @DBRider(dataSourceBeanName = \"companyDataSource\") //secondary (company) datasource will be used\n    @DataSet(\"companies.yml\")\n    public void shouldListCompanies() {\n        assertThat(companyRepository.count()).isEqualTo(2);\n        assertThat(companyRepository.findByNameLike(\"Umbrella%\")).isEqualTo(new Company(2));\n\n    }\n----\n\nTIP: Full `rider-junit5` example can be found https://github.com/database-rider/database-rider/blob/master/rider-examples/spring-boot-dbunit-sample/src/test/java/com/github/database/rider/springboot/MultipleDataSourcesTest.java#L17[here^] and https://github.com/database-rider/database-rider/blob/master/rider-junit5/src/test/java/com/github/database/rider/junit5/DBRiderSpringDataSourceIt.java#L28[here^].\n\nTIP: Full `rider-spring` example can be found https://github.com/database-rider/database-rider/blob/master/rider-spring/src/test/java/com/github/database/rider/spring/dataset/MultipleDataSourcesIt.java#L31[here^].\n\n\n==== Multiple databases in CDI tests\n\nFor `rider-cdi` you must use `entityManagerName` property of `@DBRider` from CDI module:\n\n[source, java]\n----\n@RunWith(CdiTestRunner.class)\n@DBRider\npublic class MultipleEntityManagerIt {\n\n\n    @Inject\n    EntityManager em;\n\n    @Inject\n    @RiderPU(\"cdipu2\")\n    EntityManager em2;\n\n\n    @Test\n    @DataSet(\"yml/users.yml\")\n    public void shouldListUsersFromDefaultEntityManager() {\n        List\u003cUser\u003e users = em.createQuery(\"select u from User u\").getResultList();\n        assertThat(users).isNotNull().isNotEmpty().hasSize(2);\n    }\n\n    @Test\n    @DBRider(entityManagerName = \"cdipu2\")\n    @DataSet(\"yml/users.yml\")\n    public void shouldListUsersFromEntityManager2() {\n        List\u003cUser\u003e users = em2.createQuery(\"select u from User u\").getResultList();\n        assertThat(users).isNotNull().isNotEmpty().hasSize(2);\n    }\n----\n\nTIP: Full CDI example can be found https://github.com/database-rider/database-rider/blob/master/rider-cdi/src/test/java/com/github/database/rider/cdi/MultipleEntityManagerIt.java#L27[here^].\n\n=== Expected DataSet\nUsing `@ExpectedDataSet` annotation you can specify the database state you expect after test execution, example:\n\n.expectedUsers.yml\n----\nuser:\n  - id: 1\n    name: \"expected user1\"\n  - id: 2\n    name: \"expected user2\"\n----\n\n[source, java]\n----\n    @Test\n    @ExpectedDataSet(value = \"yml/expectedUsers.yml\",ignoreCols = \"id\")\n    public void shouldMatchExpectedDataSet() {\n        User u = new User();\n        u.setName(\"expected user1\");\n        User u2 = new User();\n        u2.setName(\"expected user2\");\n        emProvider.tx().begin();\n        emProvider.em().persist(u);\n        emProvider.em().persist(u2);\n        emProvider.tx().commit();\n    }\n----\n\nNOTE: As you probably noticed, there is no need for assertions in the test itself.\n\nNow with an assertion error:\n\n[source, java]\n----\n    @Test\n    @ExpectedDataSet(value = \"yml/expectedUsers.yml\",ignoreCols = \"id\")\n    public void shouldMatchExpectedDataSet() {\n        User u = new User();\n        u.setName(\"non expected user1\");\n        User u2 = new User();\n        u2.setName(\"non expected user2\");\n        emProvider.tx().begin();\n        emProvider.em().persist(u);\n        emProvider.em().persist(u2);\n        emProvider.tx().commit();\n    }\n----\nAnd here is how the error is shown in JUnit console:\n\n----\nExpected :expected user1\nActual   :non expected user1\n \u003cClick to see difference\u003e\n\tat org.dbunit.assertion.JUnitFailureFactory.createFailure(JUnitFailureFactory.java:39)\n\tat org.dbunit.assertion.DefaultFailureHandler.createFailure(DefaultFailureHandler.java:97)\n\tat org.dbunit.assertion.DefaultFailureHandler.handle(DefaultFailureHandler.java:223)\n\tat com.github.database.rider.assertion.DataSetAssert.compareData(DataSetAssert.java:94)\n----\n\nNOTE: Since `v1.4.0` you can use \u003c\u003cDataSet Replacers\u003e\u003e in expected dataset.\n\n==== Expected DataSet with regular expressions\n\nYou can also use `regular expressions` in expected DataSet, for that just prepend column value with `regex:`:\n\n----\nuser:\n  - id: \"regex:\\\\d+\" #any number\n    name: regex:^expected user.*  #'starts with' regex\n  - id: \"regex:\\\\d+\"\n    name: regex:.*user2$   #'ends with' regex\n----\n\nNow we don't need to `ignore id column` in the above example:\n\n[source,java]\n----\n    @Test\n    @ExpectedDataSet(value = \"yml/expectedUsers.yml\")\n    public void shouldMatchExpectedDataSetUsingRegex() {\n        User u = new User();\n        u.setName(\"expected user1\");\n        User u2 = new User();\n        u2.setName(\"expected user2\");\n        emProvider.tx().begin();\n        emProvider.em().persist(u);\n        emProvider.em().persist(u2);\n        emProvider.tx().commit();\n    }\n----\n\n==== Expected Dataset with order by column\n\nTo ignore row ordering in expected dataset one can use **orderBy** attribute in expected dataset.\n\nThis way both actual and expected datasets will be ordered by same column:\n\n.expectedUsersIgnoreOrder.yml\n----\nUSER:\n  - NAME: \"@realpestano\"\n  - NAME: \"@arhohuttunen\"\n  - NAME: \"@dbunit\"\n\n----\n\n[source, java]\n----\n    @Test\n    @DataSet(value = \"yml/empty.yml\", disableConstraints = true)\n    @ExpectedDataSet(value = \"yml/expectedUsersIgnoreOrder.yml\", orderBy = \"name\")\n    public void shouldMatchExpectedDataSetIgnoringRowOrder() {\n        User u1 = new User();\n        u1.setName(\"@arhohuttunen\");\n        User u2 = new User();\n        u2.setName(\"@realpestano\");\n        User u3 = new User();\n        u3.setName(\"@dbunit\");\n        tx().begin();\n        em().persist(u1);\n        em().persist(u2);\n        em().persist(u3);\n        tx().commit();\n    }\n----\n\nNote on the example above that the order of insertion is different from declared on the dataset but the test passes because of `orderBy` will make both expected dataset and database table ordered by the same column.\n\n==== Using `CONTAINS` in expected datatset\n\nBy default the dataset you use in `@ExpectedDataSet` must be *EQUAL* to the state of the database after test execution which means same rows. \n\nSince `v1.5.2` expected dataset can be configured to use a *CONTAINS* operation and in this case its rows must be present in actual database after test.\n\n\nConsider following datasets:\n\n.users.yml\n----\nUSER:\n  - ID: 1\n    NAME: \"@realpestano\"\n  - ID: 2\n    NAME: \"@dbunit\"\n----\n\n.expectedUsersContains.yml\n----\nUSER:\n  - ID: 3\n    NAME: \"@dbrider\"\n----\n\nAnd the integration test below:\n\n[source,java]\n----\n    @Test\n    @DataSet(value = \"user.yml\", transactional = true)\n    @ExpectedDataSet(value = \"expectedUsersContains.yml\", compareOperation = CompareOperation.CONTAINS)\n    public void shouldMatchExpectedDataSetContains() {\n        User u = new User();\n        u.setId(3);\n        u.setName(\"@dbrider\");\n        em().persist(u);\n    }\n----\n\nNOTE: This test will pass if database state after test contains a row in `user table` with `id=3` and `name = @dbrider`. Other rows doesn't matter.\n\n==== Using `script assertions` in expected datatset\n\nSince `v1.31.0` it's possible to use javascript or groovy assertions (based on \u003c\u003cScriptable DataSets\u003e\u003e) in `@ExpectedDataSet`, for example consider the following dataset:\n\n```\nUSER:\n  - ID: \"js:(value \u003e 0)\"\n    NAME: \"js:(value != null \u0026\u0026 value.contains('@realpestano'))\"\n  - ID: \"groovy:(value \u003e 0)\"\n    NAME: \"groovy:(value != null \u0026\u0026 value.contains('@dbunit'))\"\n```\n\nTo enable the scripting you mainly need the `js: or groovy:` prefix *followed by an expression which evaluates to boolean* inside a `parentheses`. The `value` in the expression refers to the actual value that should be in database after the test runs.\n\n```\n    @Test\n    @DataSet(value = \"yml/empty.yml\", transactional = true)\n    @ExpectedDataSet(value = \"yml/expectedUserWithScripting.yml\")\n    public void shouldEvaluateScriptsInExpectedDataSet() {\n        User u = new User(1);\n        u.setName(\"@realpestano\");\n        User u2 = new User(2);\n        u2.setName(\"@dbunit\");\n        em().persist(u);\n        em().persist(u2);\n    }\n```\n\n\nNOTE: To enable groovy scripts you need `groovy-all` in your test classpath\n\n==== Using `Prolog` assertions in expected datatset\n\nProlog assertions enables linking column values with variables, ex:\n\nexpectedUserWithProlog.yaml\n```\nUSER:\n  - ID: $$x$$\n    NAME: \"@realpestano\"\nTWEET:\n  - ID: abcdef12345\n    CONTENT: \"dbunit rules!\"\n    USER_ID: $$x$$\n```\n\nIn the dataset above we're linking `ID` and `USER_ID` values using the `$$x$$` variable.\nTo enable this kind of assertion you need to use `compareOperation = CompareOperation.PROLOG` in `@ExpectedDataset`:\n\n----\n    @Test\n    @DataSet(value = \"yml/users.yml\", transactional = true)\n        @ExpectedDataSet(value = \"yml/expectedUserWithProlog.yml\", compareOperation = CompareOperation.PROLOG)\n    public void shouldSupportPrologCompareOperation() {\n    }\n----\n\n[TIP]\n====\nMultiple variables can be used:\n\n----\ntable1:\n  - id: $$x$$\n     name: \"name2\"\n  - id: $$y$$\n     name: \"name1\"\ntable2:\n  - table1_id: $$x$$\n  - table1_id: $$y$$\n----\n====\n\nIn case the variable values don't match an assertion error will be raised, for example:\n\n```\norg.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))\n```\n\n=== Meta DataSets\n\nWith meta datasets you can create annotations which holds `@DataSet` configuration and (re)use this custom annotation in any test:\n\n.Custom annotation holding dataset configuration\n----\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\n@DataSet(value = \"yml/users.yml\", disableConstraints = true)\npublic @interface MetaDataSet {\n\n}\n---- \n\n.Test using metadataset, @DataSet config is extracted from custom annotation \n----\n@RunWith(JUnit4.class)\n@MetaDataSet\npublic class MetaDataSetIt {\n\n\t@Rule\n\tpublic EntityManagerProvider emProvider = EntityManagerProvider.instance(\"rules-it\"); \n\n\t@Rule\n\tpublic DBUnitRule dbUnitRule = DBUnitRule.instance(emProvider.connection()); \n\n\t@Test\n\tpublic void testMetaAnnotationOnClass() {\n\t\tList\u003cUser\u003e users = em().createQuery(\"select u from User u\").getResultList();\n\t\tassertThat(users).isNotNull().isNotEmpty().hasSize(2);\n\t}\n\n}\n\n----\n\nYou can use another metadataset at method level which will take precedence:\n\n----\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\n@DataSet(value = \"yml/expectedUser.yml\", disableConstraints = true)\npublic @interface AnotherMetaDataSet {\n\n}\n---- \n \n\n----\n@RunWith(JUnit4.class)\n@MetaDataSet\npublic class MetaDataSetIt {\n\n    //rules omitted for brevity\n\n\t@Test\n\t@AnotherMetaDataSet\n\tpublic void testMetaAnnotationOnMethod() {\n\t\tList\u003cUser\u003e users = em().createQuery(\"select u from User u\").getResultList();\n\t\tassertThat(users).isNotNull().isNotEmpty().hasSize(1);\n\t}\n----\n\nNOTE: This works with all Database Rider modules like `Spring`, `CDI` and `JUnit5`.\n\nTIP: See https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/MetaDataSetIt.java[MetaDatasetIt code^] for details. \n\n\n=== Merge DataSets\n\nSince `v1.3.0` it is possible to merge @DataSet configuration by declaring the annotation at `class` and `method` level.\n\nTo enable the merging use `mergeDataSets=true` in `@DBunit` annotation or in `dbunit.yml` configuration.\n\nIMPORTANT: Only *array properties* such as `value` and  `executeScriptsAfter` from @DataSet will be merged. \n\nFollowing is an example of merging:\n\n----\n@RunWith(JUnit4.class)\n@DBUnit(mergeDataSets = true) \u003c1\u003e\n@DataSet(value=\"yml/tweet.yml\", executeScriptsAfter = \"addUser.sql\", executeStatementsBefore = \"INSERT INTO USER VALUES (8,'user8')\")\npublic class MergeDataSetsIt {\n\n    @Rule\n    public EntityManagerProvider emProvider = EntityManagerProvider.instance(\"rules-it\"); \n\n    @Rule\n    public DBUnitRule dbUnitRule = DBUnitRule.instance(emProvider.connection()); \n    \n\t\n    @Test\n    @DataSet(value=\"yml/user.yml\", executeScriptsAfter = \"tweets.sql\", executeStatementsBefore = \"INSERT INTO USER VALUES (9,'user9')\", strategy = SeedStrategy.INSERT)\n\tpublic void shouldMergeDataSetsFromClassAndMethod() {\n\t\tList\u003cUser\u003e 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'\n\t\tassertThat(users).isNotNull().isNotEmpty().hasSize(4);\n        \n        User user = (User) em().createQuery(\"select u from User u where u.id = 9\").getSingleResult(); \u003c2\u003e\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isEqualTo(9);\n        user = (User) em().createQuery(\"select u from User u where u.id = 1\").getSingleResult();\n        \n        assertThat(user.getTweets()).isNotEmpty(); \u003c3\u003e\n        assertThat(user.getTweets().get(0).getContent()).isEqualTo(\"dbunit rules again!\"); \n\t}\n\t\n    @AfterClass\n    public static void afterTest() {\n        User user = (User) em().createQuery(\"select u from User u where u.id = 10\").getSingleResult();\u003c4\u003e\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isEqualTo(10); \n        \n        Tweet tweet = (Tweet) em().createQuery(\"select t from Tweet t where t.id = 10\").getSingleResult();//scripts after\n        assertThat(tweet).isNotNull();\n        assertThat(tweet.getId()).isEqualTo(\"10\"); \n    }\n    \n}\n----\n\u003c1\u003e Activates the merging of datasets\n\u003c2\u003e User with id = 8  was inserted by `executeStatementsBefore` from class level dataset.\n\u003c3\u003e tweets comes from `tweet.yml` declared on class level dataset.\n\u003c4\u003e User with id = 10 was inserted by `addUser.sql` from class level dataset.\n\nTIP: Source code of example above can be https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/MergeDataSetsIt.java[found here^].\n\nTIP: Junit5 example can be https://github.com/database-rider/database-rider/blob/master/rider-junit5/src/test/java/com/github/database/rider/junit5/MergeDataSetsJUnit5It.java[found here^] and CDI https://github.com/database-rider/database-rider/blob/master/rider-cdi/src/test/java/com/github/database/rider/cdi/MergeDataSetsCDIIt.java[example here^].\n\n=== DataSet Replacers\n\nA DataSet replacer is a `placeholder` used in a dataset file which will be replaced during test execution. \n\nDBRider comes with a `Date Replacer`, `Null replacer`, `Include replacer` and a `Custom replacer`.\n\nTIP: For complete source code of replacers examples, https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/replacers/[see here^].\n\n==== Date replacer\n\nFollowing is an example test using a date replacer:\n\n.date-replacements.yml \n----\nTWEET:\n  - ID: \"1\"\n    CONTENT: \"dbunit rules!\"\n    DATE: \"[DAY,NOW]\"\n    USER_ID: 1\n----\n\n\n.DateReplacementsIt.java\n\n[source,java]\n----\n    @Before\n    public void setup(){\n        now = Calendar.getInstance();\n    }\n\n    @Test\n    @DataSet(value = \"date-replacements.yml\",disableConstraints = true) //disabled constraints so we can have a TWEET with inexistent USER_ID\n    public void shouldReplaceDateWithNowPlaceHolder() {\n        Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery(\"select t from Tweet t where t.id = '1'\").getSingleResult();\n        assertThat(tweet).isNotNull();\n        assertThat(tweet.getDate().get(Calendar.DAY_OF_MONTH)).isEqualTo(now.get(Calendar.DAY_OF_MONTH));\n        assertThat(tweet.getDate().get(Calendar.HOUR_OF_DAY)).isEqualTo(now.get(Calendar.HOUR_OF_DAY));\n    }\n----\n\n==== Null replacer\n\n.null-replacements.yml\n----\nTWEET:\n- ID: \"1\"\n  CONTENT: \"[null]\"\n  USER_ID: 1\n- ID: \"2\"\n  CONTENT: \"null\"\n  USER_ID: 1\n----\n\n.NullReplacementsIt.java\n[source,java]\n----\n    @Test\n    @DataSet(value = \"null-replacements.yml\", disableConstraints = true)\n    public void shouldReplaceNullPlaceholder() {\n        Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery(\"select t from Tweet t where t.id = '1'\").getSingleResult();\n        assertThat(tweet).isNotNull();\n        assertThat(tweet.getContent()).isNull();\n\n        Tweet tweet2 = (Tweet) EntityManagerProvider.em().createQuery(\"select t from Tweet t where t.id = '2'\").getSingleResult();\n        assertThat(tweet2).isNotNull();\n        assertThat(tweet2.getContent()).isNotNull().isEqualTo(\"null\");\n    }\n----\n\n==== Include replacer\n\nThis replacer let you include the content of a file inside a dataset column. For example, imagine `doc.xml` file is located at `resources/datasets/xml/doc.xml` with following content:\n\n```\n\u003cDOC ID=\"1\" CONTENT=\"XML included content\"/\u003e\nAnything in this file will be included into the column with [INCLUDE] replacement!\n```\n\nNow you can include it's content in any dataset using `[INCLUDE]` prefix:\n\n.datasets/yml/include-xml-replacements.yml\n```\nTWEET:\n  - ID: \"1\"\n    CONTENT: \"[INCLUDE]datasets/xml/doc.xml\"\n```\n\nYou just have to enable the include replacer:\n\n```\n    @Test\n    @DataSet(replacers = IncludeReplacer.class, value = \"datasets/yml/include-xml-replacements.yml\")\n    public void shouldReplaceXmlFileContent() {\n        Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery(\"select t from Tweet t where t.id = '1'\").getSingleResult();\n\n        assertThat(tweet).isNotNull();\n        assertThat(tweet.getContent()).contains(\"\u003cDOC ID=\\\"1\\\" CONTENT=\\\"XML included content\\\"/\u003e\" + NEW_LINE +\n                \"Anything in this file will be included into the column with [INCLUDE] replacement!\");\n    }\n\n```\n\n[TIP]\n====\nYou can also enable include replacer for all tests via https://github.com/database-rider/database-rider#332-dbunit-configuration[dbunit-config.yml] global config:\n\n.src/test/resources/dbunit.yml:\n----\ncacheConnection: false\ncacheTableNames: false\nleakHunter: true\nproperties:\n  batchedStatements:  true\n  qualifiedTableNames: true\n  schema:\n  replacers: [!!com.github.database.rider.core.replacers.IncludeReplacer {}]\n----\n\n====\n\n==== Custom replacer\n\nThe custom replacer makes it possible to create your own replacers. \n\nFirst we need to implement the `Replacer` interface:\n\n.CustomReplacer.java\n[source,java]\n----\n/**\n * Example implementation of Replacer which replaces string 'FOO' for 'BAR'\n *\n */\npublic class CustomReplacer implements Replacer {\n\n    @Override\n    public void addReplacements(ReplacementDataSet dataSet) {\n        dataSet.addReplacementSubstring(\"FOO\", \"BAR\");\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        return o != null \u0026\u0026 getClass() == o.getClass();\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(getClass());\n    }\n}\n----\n\n.custom-replacements.yml\n----\nTWEET:\n- ID: \"1\"\n  CONTENT: \"FOO\"\n  USER_ID: 1\n----\n\n\n.CustomReplacementIt.java\n[source,java]\n----\n@DBUnit(replacers = CustomReplacer.class) \u003c1\u003e\npublic class CustomReplacementIt {\n\n    @Rule\n    public EntityManagerProvider emProvider = EntityManagerProvider.instance(\"rules-it\");\n\n    @Rule\n    public DBUnitRule dbUnitRule = DBUnitRule.instance(\"rules-it\", emProvider.connection());\n\n    @Test\n    @DataSet(value = \"datasets/yml/custom-replacements.yml\", disableConstraints = true, executorId = \"rules-it\")\n    public void shouldReplaceFoo() {\n        Tweet tweet = (Tweet) EntityManagerProvider.em().createQuery(\"select t from Tweet t where t.id = '1'\").getSingleResult();\n        assertThat(tweet).isNotNull();\n        assertThat(tweet.getContent()).isNotNull().isEqualTo(\"BAR\");\n    }\n}\n----\n\u003c1\u003e Custom replacer is enabled via `@DBUnit` annotation `replacers` attribute.\n\n\n[TIP]\n====\nYou can also register a custom replacer for all tests via https://github.com/database-rider/database-rider#332-dbunit-configuration[dbunit-config.yml] global config:\n\n.src/test/resources/dbunit.yml:\n----\ncacheConnection: false\ncacheTableNames: false\nleakHunter: true\nproperties:\n  batchedStatements:  true\n  qualifiedTableNames: true\n  schema: public\n  batchSize: 200\n  fetchSize: 200\n  allowEmptyFields: true\n  escapePattern: \"[?]\"\n  datatypeFactory: !!com.github.database.rider.core.configuration.DBUnitConfigTest$MockDataTypeFactory {}\n  replacers: [!!com.github.database.rider.core.replacers.CustomReplacer {}]\n----\n\n====\n\n=== Scriptable DataSets\n\nScriptable datasets allows the use of `Javascript` and `Groovy` scripting inside datasets, for that you need to prefix the column content with `groovy:` or `js:`:\n\n.userWithRandomId.yml\n----\nUSER:\n  - ID: groovy:new Random().nextInt()\n    NAME: \"@realpestano\"\n  - ID: js:Math.floor(Math.random() * 999999)\n    NAME: \"@dbunit\"\n----\n\n[source, java]\n----\n    @Test\n    @DataSet(value = \"datasets/yml/userWithRandomId.yml\")\n    public void shouldReplaceUserIdUsingScriptInDataset() {\n        User user = (User) EntityManagerProvider.em().createQuery(\"select u from User u where u.name = '@dbunit'\").getSingleResult();\n        assertThat(user).isNotNull();\n        assertThat(user.getId()).isNotNull();\n    }\n----\n\n[IMPORTANT]\n====\nFor Groovy you need following dependency in classpath:\n\n----\n        \u003cdependency\u003e\n            \u003cgroupId\u003eorg.codehaus.groovy\u003c/groupId\u003e\n            \u003cartifactId\u003egroovy-all\u003c/artifactId\u003e\n            \u003cversion\u003e2.4.6\u003c/version\u003e\n            \u003cscope\u003etest\u003c/scope\u003e\n        \u003c/dependency\u003e\n----\n====\nTIP: For complete source code of scriptable datasets examples, https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/ScriptReplacementsIt.java#L19[see here^].\n\n=== DataSet providers\n\nA dataset provider is a *Java class responsible for defining a dataset* instead of having `yml`, `json`, `xml` files representing your datasets. Following are the steps for creating and using a dataset provider:\n\n. First create a class which implements `DataSetProvider` interface:\n+ \n[source, java]\n----\npublic class UserDataSetProvider implements DataSetProvider {\n\n        @Override\n        public IDataSet provide() throws DataSetException {\n            DataSetBuilder builder = new DataSetBuilder();\n            IDataSet dataSet = builder\n                    .defaultValue(\"id\", -1) //default value for all tables that don't provide a value for 'id' column\n                    .table(\"USER\") //start adding rows to 'USER' table\n                        .column(\"ID\",1)\n                        .column(name,\"@realpestano\")\n                    .row() //keeps adding rows to the current table\n                        .column(id,2)\n                        .column(\"NAME\",\"@dbunit\")\n                    .table(\"TWEET\") //starts adding rows to 'TWEET' table\n                        .defaultValue(\"LIKES\", 99) //default value only for table tweet, the value will be used if column is not specified\n                        .column(\"ID\",\"abcdef12345\")\n                        .column(\"CONTENT\",\"dbunit rules!\")\n                        .column(\"DATE\",\"[DAY,NOW]\")\n                    .table(\"FOLLOWER\").column(id,1)\n                        .column(\"USER_ID\",1)\n                        .column(\"FOLLOWER_ID\",2)\n                    .table(\"USER\")// we still can add rows to table already added\n                        .column(name,\"@new row\")\n                    .build();\n            return dataSet;\n        }\n    }\n----\n+\nThe above DataSet provider will generate a dataset like below:\n+\n----\nFOLLOWER:\n  - ID: 1\n    USER_ID: 1\n    FOLLOWER_ID: 2\n\nTWEET:\n  - ID: \"abcdef12345\"\n    CONTENT: \"dbunit rules!\"\n    DATE: \"2019-05-14 19:26:56.0\"\n    LIKES: 99\n\nUSER:\n  - ID: 1\n    NAME: \"@dbunit\"\n  - ID: 2\n    NAME: \"@dbrider\"\n  - ID: -1\n    NAME: \"@new row\"\n----\n+\nTIP: For more complex dataset examples see https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/dataset/builder/DataSetBuilderTest.java[DataSetBuilder tests here^].\n+\n\n[NOTE]\n====\nThe above dataset can be declared using `columns`...`values` syntax:\n\n----\nbuilder.defaultValue(\"id\", -1)\n       .table(\"user\")\n            .columns(\"id\", \"name\")\n            .values(1,  \"@dbrider\")\n            .values(2,  \"@dbunit\")\n            .values(null,  \"@dbunit3\")//will use default value\n       .table(\"tweet\")\n            .defaultValue(\"likes\", 99)\n            .columns(\"id\", \"content\", \"date\")\n            .values(\"abcdef12345\", \"dbunit rules!\", \"[DAY,NOW]\")\n       .table(\"follower\")\n            .columns(\"id\", \"user_id\", \"follower_id\")\n            .values(1,  1, 2)\n       .build();\n----\n\nTIP: For datasets with lots of rows and few columns this approach can fit better.\n\n====\n\n\n. Now use the DataSet provider in `@DataSet` annotation:\n+\n[source, java]\n----\n    @Test\n    @DataSet(provider = UserDataSetProvider.class, cleanBefore = true)\n    public void shouldSeedDatabaseProgrammatically() {\n        List\u003cUser\u003e users = EntityManagerProvider.em().createQuery(\"select u from User u \").getResultList();\n        assertThat(users).\n                isNotNull().\n                isNotEmpty().hasSize(3).\n                extracting(\"name\").\n                contains(\"@dbunit\", \"@dbrider\", \"@new row\");\n    }\n---- \n+\nTIP: For more examples, see dataset provider https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/DataSetProviderIt.java[tests here^].\n\nNOTE: You can also use DataSetProvider in `@ExpectedDataset` annotation.\n\n==== DataSet providers DBUnit config\n\nBy default DataSetProviders will use \u003c\u003cDBUnit Configuration, global DBUnit configuration\u003e\u003e configured in `dbunit.yml` file so you *will not be able* to use `@DBUnit` to configure providers.\n\nHowever, you can pass a DBUnit configuration when creating your dataset provider:\n\n```\n   DBUnitConfig config = new DBUnitConfig().cacheTableNames(true)\n                    .addDBUnitProperty(\"caseSensitiveTableNames\", true);\n            DataSetBuilder builder = new DataSetBuilder(config);\n            builder.table(\"USER\")\n                    .row()\n                    .column(\"ID\", 1)\n                    .column(\"NAME\", \"@dbunit\")\n                    .row()\n                    .column(\"ID\", 2)\n                    .column(\"NAME\", \"@dbrider\");\n            return builder.build();\n```\n\nNOTE: Configuration from `@DataSet` is used the same way as in file based datasets.\n\n=== RiderDSL\n\nIf you cannot rely on `@DataSet` annotation because your test runner will not read it (e.g cucumber test runner, spock, kotlin test etc...) or because you don't like annotations, you can use *RiderDSL* to create datasets:\n\n[source, java]\n----\n    @Test\n     /*same as: @DataSet(value = \"yml/user.yml\", cleanBefore=true)\n                @DBUnit(caseSensitiveTableNames = false) */\n    public void shouldSeedDatabaseUsingRiderDSL() {\n        RiderDSL.withConnection(emProvider.connection())\n                .withDataSetConfig(new DataSetConfig(\"datasets/yml/user.yml\")\n                        .cleanBefore(true))\n                .withDBUnitConfig(new DBUnitConfig().addDBUnitProperty(\"caseSensitiveTableNames\", false))\n                .createDataSet();\n        List\u003cUser\u003e users = EntityManagerProvider.em().createQuery(\"select u from User u \").getResultList();\n        assertThat(users).\n                isNotNull().\n                isNotEmpty().\n                hasSize(2);\n    }\n----\n\nTIP: See more https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/dsl/RiderDSLIt.java#L24[examples here^].\n\nSince `v1.15.0` you can also assert db state with RiderDSL as in `@ExpectedDataSet`:\n\n[source, java]\n----\n    /**\n     * same as:\n     * @DataSet(cleanBefore = true)\n     * @ExpectedDataSet(value = \"yml/expectedUsers.yml\", ignoreCols = \"id\")\n     */\n    @Test\n    public void shouldMatchExpectedDataSet() throws DatabaseUnitException {\n        RiderDSL.withConnection(emProvider.connection())\n                .cleanDB();\n        User u = new User();\n        u.setName(\"expected user1\");\n        User u2 = new User();\n        u2.setName(\"expected user2\");\n        tx().begin();\n        em().persist(u);\n        em().persist(u2);\n        tx().commit();\n        withConnection(emProvider.connection())\n                .withDataSetConfig(new DataSetConfig(\"yml/expectedUsers.yml\"))\n                .expectDataSet(new ExpectedDataSetConfig().ignoreCols(\"id\"));\n    }\n----\nTIP: See more https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/dsl/RiderDSLIt.java#L292-L375[examples here^].\n\n\n=== Dynamic connection config\n\nIn order to have dynamic JDBC connection on your tests one can use system properties, see example below:\n\n[source,java]\n----\n@RunWith(JUnit4.class)\npublic class EntityManagerSystemConfigOverrideTestIt {\n    private static final String PROP_KEY_URL = \"javax.persistence.jdbc.url\";\n    private static final String PROP_VALUE_URL = \"jdbc:hsqldb:mem:susi;DB_CLOSE_DELAY=-1\";\n    private static final String PROP_KEY_DRIVER = \"javax.persistence.jdbc.driver\";\n    private static final String PROP_KEY_USER = \"javax.persistence.jdbc.user\";\n    private static final String PROP_KEY_PASSWORD = \"javax.persistence.jdbc.password\";\n\n    @Rule\n    public EntityManagerProvider emProvider = EntityManagerProvider.instance(\"rules-it\");\n\n    @Rule\n    public DBUnitRule dbUnitRule = DBUnitRule.instance(emProvider.connection());\n\n    @BeforeClass\n    public static void setup() {\n        System.clearProperty(PROP_KEY_URL);\n        System.clearProperty(PROP_KEY_DRIVER);\n        System.clearProperty(PROP_KEY_USER);\n        System.clearProperty(PROP_KEY_PASSWORD);\n        System.setProperty(PROP_KEY_URL, \"jdbc:hsqldb:mem:susi;DB_CLOSE_DELAY=-1\");\n        System.setProperty(PROP_KEY_DRIVER, \"org.hsqldb.jdbc.JDBCDriver\");\n        System.setProperty(PROP_KEY_USER, \"sa\");\n        System.setProperty(PROP_KEY_PASSWORD, \"\");\n    }\n\n    @AfterClass\n    public static void tearDown() {\n        System.clearProperty(PROP_KEY_URL);\n        System.clearProperty(PROP_KEY_DRIVER);\n        System.clearProperty(PROP_KEY_USER);\n        System.clearProperty(PROP_KEY_PASSWORD);\n    }\n\n    //tests using new connection\n----\n\nThis way the https://github.com/database-rider/database-rider/blob/78b0ae11eeed17354f8adc6c35640a160a1447ee/rider-core/src/test/resources/META-INF/persistence.xml#L4-L20[original persistence.xml^] configuration was replaced dynamically before test execution.\n\nTIP: see source code of example above https://github.com/database-rider/database-rider/blob/78b0ae11eeed17354f8adc6c35640a160a1447ee/rider-core/src/test/java/com/github/database/rider/core/EntityManagerDynamicOverrideTestIt.java[here].\n\n=== Transactional Tests\n\nIn case of `ExpectedDataSet` you'll usually need a transaction to modify database in order to match expected dataset. In such case you can use a *transactional* test:\n\n[source, java, subs=\"quotes\"]\n----\n    @Test\n    @DataSet(*transactional=true*)\n    @ExpectedDataSet(value = \"yml/expectedUsers.yml\",ignoreCols = \"id\")\n    public void shouldMatchExpectedDataSet() {\n        User u = new User();\n        u.setName(\"non expected user1\");\n        User u2 = new User();\n        u2.setName(\"non expected user2\");\n        emProvider.em().persist(u);\n        emProvider.em().persist(u2);\n    }\n----\n\nNote that Database Rider will start a transaction before test and commit the transaction *after* test execution but *before* expected dataset comparison.\n\nBelow is a pure JDBC example where commented code is not needed because the test is transactional:\n\n[source, java, linenums]\n----\n    @Test\n    @DataSet(cleanBefore = true, transactional = true)\n    @ExpectedDataSet(value = \"usersInserted.yml\")\n    public void shouldInserUsers() throws SQLException {\n        Connection connection = flyway.getDataSource().getConnection();\n        //connection.setAutoCommit(false); //transactional=true\n        java.sql.Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,\n                ResultSet.CONCUR_UPDATABLE);\n\n        statement.addBatch(\"INSERT INTO User VALUES (1, 'user1')\");\n        statement.addBatch(\"INSERT INTO User VALUES (2, 'user2')\");\n        statement.addBatch(\"INSERT INTO User VALUES (3, 'user3')\");\n        statement.executeBatch();\n        //connection.commit();\n        //connection.setAutoCommit(false);\n    }\n----\nTIP: Above example code (which uses JUnit5 and Flyway) can be https://github.com/database-rider/database-rider/blob/master/rider-junit5/src/test/java/com/github/database/rider/junit5/FlywayIt.java#L26[found here^].\n\n=== EntityManagerProvider\n\nIt is a component which holds JPA entity managers for your tests. To activate it just use the EntityManagerProvider rule in your test use:\n\n[source,java]\n----\n@RunWith(JUnit4.class)\npublic class DatabaseRiderIt {\n\n    @Rule\n    public EntityManagerProvider emProvider = EntityManagerProvider.instance(\"PU-NAME\");\u003c1\u003e\n\n}\n----\n\u003c1\u003e It will retrieve the entity manager based on a test persistence.xml and store in into EntityManagerProvider which can hold multiple entity managers.\n\nNOTE: You can use @BeforeClass instead of junit rule to instantiate the provider.\n\nIMPORTANT: EntityManagerProvider will cache entity manager instance to avoid creating database multiple times, you just need to be careful with JPA first level cache between tests (EntityManagerProvider Rule and \u003c\u003cDBUnit Interceptor,CDI interceptor\u003e\u003e clears first level cache before each test).\n\nNow you can use emProvider.getConnection() to retrieve jdbc connection and emProvider.em() to retrieve underlying entityManager.\n\n*PU-NAME* refers to test persistence.xml unit name:\n\n.src/test/resources/META-INF/persistence.xml\n[source,java]\n----\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cpersistence version=\"2.0\" xmlns=\"http://java.sun.com/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd\"\u003e\n\n    \u003cpersistence-unit name=\"PU-NAME\" transaction-type=\"RESOURCE_LOCAL\"\u003e\n\n    \u003cclass\u003ecom.github.database.rider.model.User\u003c/class\u003e\n    \u003cclass\u003ecom.github.database.rider.model.Tweet\u003c/class\u003e\n    \u003cclass\u003ecom.github.database.rider.model.Follower\u003c/class\u003e\n\n    \u003cproperties\u003e\n        \u003cproperty name=\"javax.persistence.jdbc.url\" value=\"jdbc:hsqldb:mem:test;DB_CLOSE_DELAY=-1\"/\u003e\n        \u003cproperty name=\"javax.persistence.jdbc.driver\" value=\"org.hsqldb.jdbcDriver\"/\u003e\n        \u003cproperty name=\"javax.persistence.schema-generation.database.action\" value=\"drop-and-create\"/\u003e\n        \u003cproperty name=\"javax.persistence.jdbc.user\" value=\"sa\"/\u003e\n        \u003cproperty name=\"javax.persistence.jdbc.password\" value=\"\"/\u003e\n        \u003cproperty name=\"eclipselink.logging.level\" value=\"INFO\"/\u003e\n        \u003cproperty name=\"eclipselink.logging.level.sql\" value=\"FINE\"/\u003e\n        \u003cproperty name=\"eclipselink.logging.parameters\" value=\"false\"/\u003e\n    \u003c/properties\u003e\n\n    \u003c/persistence-unit\u003e\n\n\u003c/persistence\u003e\n----\nNOTE: It will only work with *transaction-type=\"RESOURCE_LOCAL\"* because internally it uses Persistence.createEntityManagerFactory(unitName) to get entityManager instance.\n\nAbove JPA configuration depends on hsqldb (an in memory database) and eclipse link (JPA provider):\n\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.eclipse.persistence\u003c/groupId\u003e\n    \u003cartifactId\u003eeclipselink\u003c/artifactId\u003e\n    \u003cversion\u003e2.5.2\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.hsqldb\u003c/groupId\u003e\n    \u003cartifactId\u003ehsqldb\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.3\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n----\n\nNOTE: A hibernate entity manager config sample can be https://github.com/database-rider/database-rider/blob/master/rider-examples/src/test/resources/META-INF/persistence.xml[found here^].\n\n\nTIP: EntityManager provider utility also can be used in other contexts like a CDI producer, https://github.com/database-rider/database-rider/blob/master/rider-cdi/src/test/java/com/github/database/rider/cdi/EntityManagerProducer.java#L21[see here].\n\n\n== CDI module\n\nIf you use CDI in your tests then you should give a try in Database Rider https://github.com/database-rider/database-rider/tree/master/rider-cdi[CDI module^]:\n\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.database-rider\u003c/groupId\u003e\n    \u003cartifactId\u003erider-cdi\u003c/artifactId\u003e\n    \u003cversion\u003e1.44.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n----\n\nTIP: Use `jakarta` maven classifier if you use jakarta-cdi or jakarta-persistence\n\n=== DBUnit Interceptor\n\nCDI module main component is a CDI interceptor which configures datasets before your tests. To enable DBUnit interceptor you'll need\nconfigure it in you test beans.xml:\n\n.src/test/resources/META-INF/beans.xml\n[source,xml]\n----\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cbeans xmlns=\"http://java.sun.com/xml/ns/javaee\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd\"\u003e\n\n       \u003cinterceptors\u003e\n              \u003cclass\u003ecom.github.database.rider.cdi.DBUnitInterceptorImpl\u003c/class\u003e\n       \u003c/interceptors\u003e\n\u003c/beans\u003e\n\n----\n\nand then enable it in your tests by using *@DBUnitInterceptor* annotation (class or method level):\n\n[source,java]\n----\n@RunWith(CdiTestRunner.class)\n@DBUnitInterceptor\npublic class DeltaspikeUsingInterceptorIt {\n\n    @Inject\n    DeltaSpikeContactService contactService;\n\n\n    @Test\n    @DataSet(\"datasets/contacts.yml\")\n    public void shouldQueryAllCompanies() {\n        assertNotNull(contactService);\n        assertThat(contactService.findCompanies()).hasSize(4);\n    }\n}\n----\n\n[IMPORTANT]\n====\nMake sure the test class itself is a CDI bean so it can be intercepted by `DBUnitInterceptor`. If you're using https://deltaspike.apache.org/documentation/test-control.html[Deltaspike test control^] just enable the following\nproperty in test/resources/META-INF/apache-deltaspike.properties:\n----\n   deltaspike.testcontrol.use_test_class_as_cdi_bean=true\n----\n====\n\n== Cucumber module\n\nthis module brings a Cucumber runner which is CDI aware.\n\nNOTE: If you don't use CDI you'll need to https://github.com/database-rider/database-rider#programmatic-creating-datasets[create datasets programmatically] because Cucumber `official` runner https://github.com/cucumber/cucumber-jvm/issues/393[doesn't support JUnit rules^].\n\n\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.database-rider\u003c/groupId\u003e\n    \u003cartifactId\u003erider-cucumber\u003c/artifactId\u003e\n    \u003cversion\u003e1.44.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n----\n\nNow you just need to use *CdiCucumberTestRunner*.\n\n=== Examples\n\n.feature file (src/test/resources/features/contacts.feature)\n----\nFeature: Contacts test\n  As a user of contacts repository\n  I want to crud contacts\n  So that I can expose contacts service\n\n\n  Scenario Outline: search contacts\n    Given we have a list of constacts\n    When we search contacts by name \"\u003cname\u003e\"\n    Then we should find \u003cresult\u003e contacts\n\n  Examples: examples1\n  | name     | result |\n  | delta    | 1      |\n  | sp       | 2      |\n  | querydsl | 1      |\n  | abcd     | 0      |\n\n\n  Scenario: delete a contact\n\n    Given we have a list of contacts\n    When we delete contact by id 1\n    Then we should not find contact 1\n----\n\n.Cucumber cdi runner\n[source,java]\n----\npackage com.github.database.rider.examples.cucumber;\n\nimport com.github.database.rider.cucumber.CdiCucumberTestRunner;\nimport cucumber.api.CucumberOptions;\nimport org.junit.runner.RunWith;\n\n\n@RunWith(CdiCucumberTestRunner.class)\n@CucumberOptions(\n        features = {\"src/test/resources/features/contacts.feature\"},\n        plugin = {\"json:target/cucumber.json\"}\n        //glue = \"com.github.database.rider.examples.glues\" \u003c1\u003e\n)\npublic class ContactFeature {\n}\n----\n\n\u003c1\u003e You can use glues so step definitions and the runner can be in different packages for reuse between features.\n\n.Step definitions\n[source,java]\n----\npackage com.github.database.rider.examples.cucumber; //\u003c1\u003e\n\nimport com.github.database.rider.api.dataset.DataSet;\nimport cucumber.api.java.en.Given;\nimport cucumber.api.java.en.Then;\nimport cucumber.api.java.en.When;\nimport org.example.jpadomain.Contact;\nimport org.example.jpadomain.Contact_;\nimport org.example.service.deltaspike.ContactRepository;\n\nimport javax.inject.Inject;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\n@DBUnitInterceptor \u003c2\u003e\npublic class ContactSteps {\n\n    @Inject\n    ContactRepository contactRepository;\n\n    Long count;\n\n    @Given(\"^we have a list of contacts\")\n    @DataSet(\"datasets/contacts.yml\") //\u003c2\u003e\n    public void given() {\n        assertEquals(contactRepository.count(), new Long(3));\n    }\n\n    @When(\"^^we search contacts by name \\\"([^\\\"]*)\\\"$\")\n    public void we_search_contacts_by_name_(String name) throws Throwable {\n        Contact contact = new Contact();\n        contact.setName(name);\n        count = contactRepository.countLike(contact, Contact_.name);\n    }\n\n\n    @Then(\"^we should find (\\\\d+) contacts$\")\n    public void we_should_find_result_contacts(Long result) throws Throwable {\n        assertEquals(result,count);\n    }\n\n\n    @When(\"^we delete contact by id (\\\\d+)$\")\n    public void we_delete_contact_by_id(long id) throws Throwable {\n        contactRepository.remove(contactRepository.findBy(id));\n    }\n\n    @Then(\"^we should not find contact (\\\\d+)$\")\n    public void we_should_not_find_contacts_in_database(long id) throws Throwable {\n        assertNull(contactRepository.findBy(id));\n    }\n}\n----\n\n\u003c1\u003e Step definitions must be in the same package of the runner. To use different package you can use *glues* as commented above.\n\u003c2\u003e Activates DBUnit CDI interceptor which will read @DataSet annotation in cucumber steps to prepare the database.\n\n== Programmatic creating datasets\n\nYou can create datasets without JUnit Rule or CDI as we saw above, here is a pure cucumber example (for the same https://github.com/database-rider/database-rider#51-examples[feature above]):\n\nNOTE: If you are looking for a way to *define datasets programmatically* look into \u003c\u003cDataSet providers\u003e\u003e.\n\n[source,java,linenums]\n----\n@RunWith(Cucumber.class)\n@CucumberOptions(\n        features = {\"src/test/resources/features/contacts-without-cdi.feature\"},\n        plugin = {\"json:target/cucumber.json\"}\n        //glue = \"com.github.database.rider.examples.glues\"\n)\npublic class ContactFeatureWithoutCDI {\n}\n----\n\nAnd here are the step definitions:\n\n[source,java,linenums]\n----\npublic class ContactStepsWithoutCDI {\n\n\n    EntityManagerProvider entityManagerProvider = EntityManagerProvider.newInstance(\"customerDB\");\n\n    DataSetExecutor dbunitExecutor;\n\n    Long count;\n\n\n    @Before\n    public void setUp(){\n        dbunitExecutor = DataSetExecutorImpl.instance(new ConnectionHolderImpl(entityManagerProvider.connection()));\n        em().clear();//important to clear JPA first level cache between scenarios\n    }\n\n\n    @Given(\"^we have a list of contacts2$\")\n    public void given() {\n        dbunitExecutor.createDataSet(new DataSetConfig(\"contacts.yml\"));\n        assertEquals(em().createQuery(\"select count(c.id) from Contact c\").getSingleResult(), new Long(3));\n    }\n\n    @When(\"^^we search contacts by name \\\"([^\\\"]*)\\\"2$\")\n    public void we_search_contacts_by_name_(String name) throws Throwable {\n        Contact contact = new Contact();\n        contact.setName(name);\n        Query query =  em().createQuery(\"select count(c.id) from Contact c where UPPER(c.name) like :name\");\n        query.setParameter(\"name\",\"%\"+name.toUpperCase()+\"%\");\n        count = (Long) query.getSingleResult();\n    }\n\n\n    @Then(\"^we should find (\\\\d+) contacts2$\")\n    public void we_should_find_result_contacts(Long result) throws Throwable {\n        assertEquals(result,count);\n    }\n\n\n\n    @When(\"^we delete contact by id (\\\\d+) 2$\")\n    public void we_delete_contact_by_id(long id) throws Throwable {\n        tx().begin();\n        em().remove(em().find(Contact.class,id));\n        tx().commit();\n    }\n\n    @Then(\"^we should not find contact (\\\\d+) 2$\")\n    public void we_should_not_find_contacts_in_database(long id) throws Throwable {\n        assertNull(em().find(Contact.class,id));\n    }\n}\n----\n\nTIP: For a fluent API to create datasets, you can use \u003c\u003cRiderDSL\u003e\u003e instead of DataSetExecutor.\n\n== JUnit 5\n\nhttp://junit.org/junit5/[JUnit 5] is the new version of JUnit and comes with a new extension model, so instead of *rules* you will use extensions in your tests. See example below:\n\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.database-rider\u003c/groupId\u003e\n    \u003cartifactId\u003erider-junit5\u003c/artifactId\u003e\n    \u003cversion\u003e1.44.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n----\n\nTIP: Use `jakarta` maven classifier if your project uses jakarta dependencies such as jakarta-persistence\n\n\n\n[source,java,linenums]\n----\n@ExtendWith(DBUnitExtension.class)\n@RunWith(JUnitPlatform.class)\npublic class DBUnitJUnit5Test {\n\n    private ConnectionHolder connectionHolder = () -\u003e instance(\"junit5-pu\").connection(); \u003c1\u003e\n\n    @BeforeAll\n    @DataSet(\"empty.yml\")\n    public static void setUp() {\n    }\n\n    @BeforeEach\n    @DataSet(\"users.yml\")\n    public static void setUp() {\n    }\n\n    @Test\n    @DataSet(value = \"usersWithTweet.yml\")\n    public void shouldListUsers() {\n        List\u003cUser\u003e users = em().createQuery(\"select u from User u\").getResultList();\n        assertThat(users).isNotNull().isNotEmpty().hasSize(2);\n    }\n----\n\u003c1\u003e DBUnit extension will get JDBC connection by reflection so you need to declare a *field* or *method* with `ConnectionHolder` as return type.\n\n[IMPORTANT]\n====\nIf you use the EntityManagerProducer in your junit5 tests ensure to use the class from the package `com.github.database.rider.junit5.util`. This class works but is marked as @Deprecated and will be removed in the 2.0.0 release. For testing purposes you can try the 'new one' from `com.github.database.rider.core.util`. To make this working you need to import '@DBRider' and DBUnitExtension from the `com.github.database.rider.junit5.incubating` packages. Don't forget to set these imports to their defaults when version 2.0.0 is released.\n\n====\n\n[IMPORTANT]\n====\n\nIf you use SpringBoot extension for JUnit5 you don't need to declare the field or method, see an https://github.com/database-rider/database-rider/blob/master/rider-examples/spring-boot-dbunit-sample/src/test/java/com/github/database/rider/springboot/SpringBootDBUnitTest.java#L19[example here^].\n\nTIP: If you're using JUnit4 and SpringTestRunner, see \u003c\u003cSpring, Rider Spring module\u003e\u003e\n====\n\nTIP: You can configure JDBC connection using @DBUnit annotation or dbunit.yml, see \u003c\u003cJDBC Connection\u003e\u003e.\n\n[NOTE]\n====\nYou can use `@DBRider` (at test or method level) to enable the extension: \n\n[source,java]\n----\n@RunWith(JUnitPlatform.class)\npublic class DBRiderAnnotationIt {\n\n    private ConnectionHolder connectionHolder = () -\u003e\n            EntityManagerProvider.instance(\"junit5-pu\").connection();\n\n    @DBRider //shortcut for @ExtendWith(DBUnitExtension.class) and @Test\n    @DataSet(value = \"usersWithTweet.yml\")\n    public void shouldListUsers() {\n        List users = EntityManagerProvider.em().\n                createQuery(\"select u from User u\").getResultList();\n        assertThat(users).isNotNull().isNotEmpty().hasSize(2);\n        assertThat(users.get(0)).isEqualTo(new User(1));\n    }\n}\n----\n====\n\n== Spring\n\nAdd Database Rider Spring extension to your project\n\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.database-rider\u003c/groupId\u003e\n    \u003cartifactId\u003erider-spring\u003c/artifactId\u003e\n    \u003cversion\u003e1.44.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n----\n\nTo enable Database Rider tests use `@DBRider` annotation (from `rider-spring` module), example:\n\n[source, java, linenums]\n----\n@RunWith(SpringRunner.class)\n@SpringBootTest\n@DBRider\npublic class SpringBootDBUnitTest {\n\n    @Autowired\n    private UserRepository userRepository;\n\n    @Test\n    @DataSet(\"users.yml\")\n    @ExpectedDataSet(\"expectedUsers.yml\")\n    public void shouldDeleteUser() throws Exception {\n        assertThat(userRepository).isNotNull();\n        assertThat(userRepository.count()).isEqualTo(3);\n        userRepository.delete(userRepository.findOne(2L));\n    }\n}\n----\n\nDatabase Rider will access to database via dataSource registered in application context.\n\nIMPORTANT: This module is designed to work with *JUnit4* and *SpringRunner*, for JUnit5 please use `@DBRider` annotation from `JUnit5` module, see an https://github.com/database-rider/database-rider/blob/master/rider-examples/spring-boot-dbunit-sample/src/test/java/com/github/database/rider/springboot/SpringBootDBUnitTest.java#L19[example here^].\n\n\n== Quarkus\n\nAs Quarkus tests are CDI beans you can just use `@DBRider` from \u003c\u003cCDI module, CDI module\u003e\u003e:\n\n```\n@QuarkusTest\n@DBRider\npublic class QuarkusDBUnitTest {\n\n    @Inject\n    BookRepository repository;\n\n    @Test\n    @DataSet(value = \"books.yml\")\n    public void shouldFindAllBooks() {\n        List\u003cBook\u003e books = repository.findAll().list();\n        assertThat(books)\n                .isNotNull()\n                .hasSize(4)\n                .extracting(\"title\")\n                .contains(\"H2G2\",\"Dune\", \"Nineteen Eighty-Four\", \"The Silmarillion\");\n    }\n\n    @Test\n    @DataSet(value = \"books.yml\")\n    public void shouldFindAllBooksViaRestApi() {\n        given()\n             .when().get(\"/api/books\")\n             .then()\n             .statusCode(OK.getStatusCode())\n             .body(\"\", hasSize(4))\n             .body(\"title\", hasItem(\"The Silmarillion\"));\n    }\n}\n\n```\n\nTIP: See full https://github.com/database-rider/database-rider/blob/master/rider-examples/quarkus-dbunit-sample/src/test/java/com/github/quarkus/sample/QuarkusDBUnitTest.java[example here^].\n\n== Micronaut\n\nYou can use DBRider in Micronaut JUnit5 tests:\n\n```\n@MicronautTest\n@com.github.database.rider.junit5.api.DBRider\npublic class PetRepositoryTest {\n\n    @Inject\n    PetRepository petRepository;\n\n    @Test\n    @DataSet(\"pets.yml\")\n    void testRetrievePetAndOwner() {\n        Pet lassie = petRepository.findByName(\"Lassie\").orElse(null);\n        assertNotNull(lassie);\n        assertEquals(\"Lassie\", lassie.getName());\n        assertEquals(\"Fred\", lassie.getOwner().getName());\n    }\n}\n```\n\nTIP: See full https://github.com/database-rider/database-rider/blob/master/rider-examples/rider-micronaut/src/test/java/example/repositories/PetRepositoryTest.java[example here^].\n\n== Leak Hunter\n\nLeak hunter is a component based on https://vladmihalcea.com/2016/07/12/the-best-way-to-detect-database-connection-leaks/[this blog post^] which counts open jdbc connections before and after test execution.\n\nTo enable it just use *leakHunter = true* in `@DBUnit` annotation, example:\n\n[source, java, linenums]\n----\n@RunWith(JUnit4.class)\n@DBUnit(leakHunter = true)\npublic class LeakHunterIt {\n\n    @Rule\n    public DBUnitRule dbUnitRule = DBUnitRule.instance(new ConnectionHolderImpl(getConnection()));\n\n    @Rule\n    public ExpectedException exception = ExpectedException.none();\n\n    @Test\n    @DataSet(\"yml/user.yml\")\n    public void shouldFindConnectionLeak() {\n         exception.expect(LeakHunterException.class); \u003c1\u003e\n         exception.expectMessage(\"Execution of method shouldFindConnectionLeak left 1 open connection(s).\");\n         createLeak();\n     }\n\n     @Test\n     @DataSet(\"yml/user.yml\")\n     public void shouldFindTwoConnectionLeaks()  {\n         exception.expect(LeakHunterException.class);\n         exception.expectMessage(\"Execution of method shouldFindTwoConnectionLeaks left 2 open connection(s).\");\n         createLeak();\n         createLeak();\n     }\n\n     @Test\n     @DataSet(\"yml/user.yml\")\n     @DBUnit(leakHunter = false)\n     public void shouldNotFindConnectionLeakWhenHunterIsDisabled() {\n           createLeak();\n     }\n\n}\n----\n\u003c1\u003e If number of connections after test execution are greater than before then a *LeakHunterException* will be raised.\n\nTIP: Complete source code of example above can be https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/LeakHunterIt.java[found here^].\n\n== Export DataSets\n\nManual creation of datasets is a very error prone task. In order to export database state *after test* execution into datasets files or \u003c\u003cDataSet providers, DataSetBuilder\u003e\u003e one can use *@ExportDataSet* Annotation or use DataSetExporter component.\n\n=== Example\n\n[source, java, linenums]\n----\n    @Test\n    @DataSet(\"datasets/yml/users.yml\")\n    @ExportDataSet(format = DataSetFormat.XML,outputName=\"target/exported/xml/allTables.xml\")\n    public void shouldExportAllTablesInXMLFormat() {\n       //data inserted inside method can be exported\n    }\n----\n\nAfter above test execution all tables will be exported to a xml dataset.\n\n\nNOTE: *XML*, *YML*, *JSON*, *XLS*, *XLSX* and *CSV* formats are supported.\n\nFor generating `DataSetBuilder` code you just need to specify *builderType* attribute in `@ExportDataSet`:\n\n[source, java]\n----\n    @Test\n    @DataSet(\"datasets/yml/users.yml\") //\u003c1\u003e\n    @ExportDataSet(format = DataSetFormat.XML, outputName = \"target/exported/xml/AllTables.xml\", builderType = BuilderType.DEFAULT)\n    public void shouldExportDataSetAsBuilderInDefaultSyntax() {\n        //AllTables.java file containing DataSetBuilder code will be generated along with AllTables.xml file.\n    }\n\n    @Test\n    @DataSet(\"datasets/yml/users.yml\") //\u003c1\u003e\n    @ExportDataSet(format = DataSetFormat.XML, outputName = \"target/exported/xml/AllTables2.xml\", builderType = BuilderType.COLUMNS_VALUES)\n    public void shouldExportDataSetAsBuilderInColumnValuesSyntax() {\n        //AllTables.java file containing DataSetBuilder code will be generated along with AllTables2.xml file.\n    }\n----\n\nTIP: Full example above (and other related tests) can be https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/java/com/github/database/rider/core/exporter/ExportDataSetIt.java#L32[found here^].\n\n=== Configuration\n\nFollowing table shows all exporter configuration options:\n\n[cols=\"3*\", options=\"header\"]\n|===\n|Name | Description | Default\n|format| Exported dataset file format.| YML\n|includeTables| A list of table names to include in exported dataset.| Default is empty which means *ALL tables*.\n|queryList| A list of select statements which the result will used in exported dataset.| {}\n|dependentTables| If true will bring dependent tables of declared includeTables.| false\n|outputName| Name (and path) of output file.| \"\"\n|===\n\n\n=== Programatic export\n\nYou can also export DataSets without `@ExportDataSet` by using DataSetExporter component programmatically:\n\n[source,java,linenums]\n----\n    @Test\n    @DataSet(cleanBefore=true)\n    public void shouldExportYMLDataSetWithoutAnnotations() throws SQLException, DatabaseUnitException{\n    \ttx().begin();\n    \tUser u1 = new User();\n    \tu1.setName(\"u1\");\n    \tem().persist(u1);//just insert a user and assert it is present in exported dataset\n    \ttx().commit();\n    \tDataSetExporter.getInstance().export(emProvider.connection(),\n    \tnew DataSetExportConfig().outputFileName(\"target/user.yml\"));\n    \tFile ymlDataSet = new File(\"target/user.yml\");\n        assertThat(ymlDataSet).exists();\n        assertThat(contentOf(ymlDataSet)).\n               contains(\"USER:\"+NEW_LINE +\n                  \"  - ID: 1\"+NEW_LINE +\n                  \"    NAME: \\\"u1\\\"\"+NEW_LINE);\n\n    }\n----\n\n=== DBUnit addon\n\nYou can export datasets using https://forge.jboss.org/[JBoss forge^], see https://github.com/database-rider/dbunit-addon/[DBUnit Addon^].\n\n\n== Examples\n\nThere are a lot of examples that can also be used as documentation.\n\nThe examples module which contains:\n\n* https://github.com/database-rider/database-rider/tree/master/rider-examples/jpa-productivity-boosters[JPA productivity boosters^]\n* https://github.com/database-rider/database-rider/tree/master/rider-examples/dbunit-tomee-appcomposer-sample[DBUnit Application Composer^]\n* https://github.com/database-rider/database-rider/tree/master/rider-examples/jOOQ-DBUnit-flyway-example/[jOOQ Flyway DBUnit^]\n* https://github.com/database-rider/database-rider/tree/master/rider-examples/spring-boot-dbunit-sample/[SpringBoot Data DBUnit^]\n* https://github.com/rmpestano/spring-events/blob/master/src/test/java/com/sambrannen/spring/events/repository/EventRepositoryTests.java#L47[Gradle, SpringBoot and JUnit5 example^]\n* https://github.com/database-rider/database-rider/tree/master/rider-examples/quarkus-dbunit-sample/[Quarkus DBUnit^]\n* https://github.com/database-rider/database-rider/tree/master/rider-examples/rider-micronaut/[Rider Micronaut^]\n\nAnd also each module contain a lot of tests that you can use as example.\n\n== Changelog\n\nSee https://github.com/database-rider/database-rider/releases[project releases on github^] for tracking changes per release.\n\n== Snapshots\n\nSnapshots are available in maven central, to use it just add the following snippet in your pom.xml:\n\n[source,xml]\n----\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003csnapshots/\u003e\n        \u003cid\u003esnapshots\u003c/id\u003e\n        \u003cname\u003elibs-snapshot\u003c/name\u003e\n        \u003curl\u003ehttps://oss.sonatype.org/content/repositories/snapshots\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n----\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatabase-rider%2Fdatabase-rider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatabase-rider%2Fdatabase-rider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatabase-rider%2Fdatabase-rider/lists"}