{"id":15043364,"url":"https://github.com/zapodot/embedded-db-junit","last_synced_at":"2025-04-06T03:08:41.176Z","repository":{"id":25166981,"uuid":"28589967","full_name":"zapodot/embedded-db-junit","owner":"zapodot","description":"JUnit Rule for providing an embedded in-memory database for your tests","archived":false,"fork":false,"pushed_at":"2024-10-10T04:31:01.000Z","size":995,"stargazers_count":60,"open_issues_count":17,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-30T02:06:22.625Z","etag":null,"topics":["flyway","h2-database","hsqldb","java","jdbc","junit","junit-rule","liquibase","sql","testing"],"latest_commit_sha":null,"homepage":"https://embedded-db-junit.zapodot.org","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zapodot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","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":"2014-12-29T11:25:35.000Z","updated_at":"2024-07-31T11:30:16.000Z","dependencies_parsed_at":"2024-01-26T12:11:38.535Z","dependency_job_id":"2e3c205e-f3b1-46fd-b19c-ee26760092c2","html_url":"https://github.com/zapodot/embedded-db-junit","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zapodot%2Fembedded-db-junit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zapodot%2Fembedded-db-junit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zapodot%2Fembedded-db-junit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zapodot%2Fembedded-db-junit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zapodot","download_url":"https://codeload.github.com/zapodot/embedded-db-junit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247427006,"owners_count":20937201,"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":["flyway","h2-database","hsqldb","java","jdbc","junit","junit-rule","liquibase","sql","testing"],"created_at":"2024-09-24T20:48:54.708Z","updated_at":"2025-04-06T03:08:41.146Z","avatar_url":"https://github.com/zapodot.png","language":"Java","funding_links":[],"categories":["测试"],"sub_categories":[],"readme":"embedded-db-junit\n=================\n\n[![Build Status](https://github.com/zapodot/embedded-db-junit/actions/workflows/maven.yml/badge.svg)](https://github.com/zapodot/embedded-db-junit/actions/workflows/maven.yml)\n[![Coverage status](https://codecov.io/gh/zapodot/embedded-db-junit/branch/master/graph/badge.svg?token=SvKrWdPu5e)](https://codecov.io/gh/zapodot/embedded-db-junit)\n[![Maven Central](https://img.shields.io/maven-central/v/org.zapodot/embedded-db-junit.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.zapodot%22%20AND%20a%3A%22embedded-db-junit%22)\n[![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](//github.com/zapodot/embedded-db-junit/blob/master/LICENSE)\n[![Open Source Helpers](https://www.codetriage.com/zapodot/embedded-db-junit/badges/users.svg)](https://www.codetriage.com/zapodot/embedded-db-junit)\n[![Follow me @ Twitter](https://img.shields.io/twitter/follow/zapodot.svg?style=social\u0026label=Follow)](https://twitter.com/intent/follow?screen_name=zapodot)\n\n[JUnit](http://junit.org/) Rule that provides a in-memory database (both [H2](http://www.h2database.com/) and [HyperSQL](http://hsqldb.org) are supported). It is compatible with all known JDBC access libraries such as [Spring JDBC](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html#jdbc-introduction), [RX-JDBC](//github.com/davidmoten/rxjava-jdbc), [sql2o](http://www.sql2o.org/), [JDBI](http://jdbi.org/) or plain old JDBC.\n\n## Why?\n* because you want to test the SQL code executed by your code without integrating with an actual DB server\n* removes the need of having a database server running and available\n* you are refactoring legacy code where JDBC calls is tightly coupled with your business logic and wants to start by testing the legacy code from the \"outside\" (as suggested by [Michael Feathers](http://www.informit.com/store/working-effectively-with-legacy-code-9780131177055?aid=15d186bd-1678-45e9-8ad3-fe53713e811b))\n* you want to test your database evolutions with either they are maintened using [Liquibase](./embedded-db-junit-liquibase/) or [Flyway](./embedded-db-flyway/).\n\n## Status\nThis library is distributed through the [Sonatype OSS repo](https://oss.sonatype.org/) and should thus be widely available.\n\n| Version | Java version | JUnit version | H2 version | HSQLDB version | Branch                                                                       | Status        |\n|---------|--------------| ------------- | ---------- |----------------|------------------------------------------------------------------------------|---------------|\n| 2.2.X   | 17           | 4.13/5.X      | 2.1.X      | 2.7.x          | [`master`](//github.com/zapodot/embedded-db-junit/tree/master)               | `active`      |\n| 2.1.X   | 11           | 4.13/5.X      | 2.1.X      | 2.7.0          | [`release-2.1.x`](//github.com/zapodot/embedded-db-junit/tree/release-2.1.x) | `maintenance`      |\n| 2.0.X   | 8.0          | 4.12/5.X      | 1.4.200    | 2.5.0          | [`release-2.0.x`](//github.com/zapodot/embedded-db-junit/tree/release-2.0.x) | `obsolete` |\n| 1.1.X   | 8.0          | 4.12          | 1.4.200    | 2.4.0          | [`release-1.1.x`](//github.com/zapodot/embedded-db-junit/tree/release-1.1.x) | `obsolete`    |\n| 1.0     | 1.7          | 4.12          | 1.4.196    | N/A            | [`release-1.x`](//github.com/zapodot/embedded-db-junit/tree/release-1.x)     | `obsolete`    | \n\nThe versions that is described in this table are minimum versions. Later versions may be used but is currently not tested by the maintainer.\n\n## Usage\n\n### Add dependency\n#### Maven\n\n#### For JUnit 5 Jupiter\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.zapodot\u003c/groupId\u003e\n    \u003cartifactId\u003eembedded-db-junit-jupiter\u003c/artifactId\u003e\n    \u003cversion\u003e2.1.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n#### For JUnit 4.X\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.zapodot\u003c/groupId\u003e\n    \u003cartifactId\u003eembedded-db-junit\u003c/artifactId\u003e\n    \u003cversion\u003e2.1.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n##### Liquibase plugin\nIf you want to use the [Liquibase](//github.com/zapodot/embedded-db-junit/tree/master/embedded-db-junit-liquibase) plugin:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.zapodot\u003c/groupId\u003e\n    \u003cartifactId\u003eembedded-db-junit-liquibase\u003c/artifactId\u003e\n    \u003cversion\u003e2.1.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n##### Flyway plugin\nIf you want to use the [Flyway](//github.com/zapodot/embedded-db-junit/tree/master/embedded-db-flyway) plugin:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.zapodot\u003c/groupId\u003e\n    \u003cartifactId\u003eembedded-db-flyway\u003c/artifactId\u003e\n    \u003cversion\u003e2.1.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n#### SBT\n```scala\nlibraryDependencies += \"org.zapodot\" % \"embedded-db-junit\" % \"2.1.0\" % \"test\"\n```\n\n### Add to Junit test\n#### Junit 5.X Jupiter\n##### Declarative style using annotations\n```java\n@EmbeddedDatabaseTest(\n        engine = Engine.HSQLDB,\n        initialSqls = \"CREATE TABLE Customer(id INTEGER PRIMARY KEY, name VARCHAR(512)); \"\n                    + \"INSERT INTO CUSTOMER(id, name) VALUES (1, 'John Doe')\"\n)\nclass EmbeddedDatabaseExtensionExtendWithTest {\n\n    @Test\n    void testUsingSpringJdbc(final @EmbeddedDatabase DataSource dataSource) {\n        final JdbcOperations jdbcOperation = new JdbcTemplate(dataSource);\n        final int id = 2;\n        final String customerName = \"Jane Doe\";\n    \n        final int updatedRows = jdbcOperation.update(\"INSERT INTO CUSTOMER(id, name) VALUES(?,?)\", id, customerName);\n    \n        assertEquals(1, updatedRows);\n        assertEquals(customerName, jdbcOperation.queryForObject(\"SELECT name from CUSTOMER where id = ?\", String.class, id));\n\n    }\n    \n    void testUsingConnection(final @EmbeddedDatabase Connection connection) {\n         try(final Statement statement = connection.createStatement();\n             final ResultSet resultSet = statement.executeQuery(\"SELECT * from CUSTOMER\")) {\n                assertTrue(resultSet.next());\n         }\n    } \n\n}\n```\n\n##### Fluent style using builder and @RegisterExtension\n```java\nclass EmbeddedDatabaseExtensionRegisterExtensionHSQLDBTest {\n\n    @RegisterExtension\n    static EmbeddedDatabaseExtension embeddedDatabaseExtension = EmbeddedDatabaseExtension.Builder.hsqldb()\n                                            .withInitialSql(\"CREATE TABLE Customer(id INTEGER PRIMARY KEY, name VARCHAR(512)); \"\n                                                          + \"INSERT INTO CUSTOMER(id, name) VALUES (1, 'John Doe')\")\n                                            .build();\n\n\n    @Test\n    void doDatabaseCall() throws SQLException {\n        assertEquals(\"HSQL Database Engine\", embeddedDatabaseExtension.getConnection().getMetaData().getDatabaseProductName());\n    }\n\n}\n```\n\n#### Junit 4.X\n```java\n@Rule\npublic final EmbeddedDatabaseRule dbRule = EmbeddedDatabaseRule\n                                        .builder()\n                                        .withMode(CompatibilityMode.Oracle)\n                                        .withInitialSql(\"CREATE TABLE Customer(id INTEGER PRIMARY KEY, name VARCHAR(512)); \"\n                                                        + \"INSERT INTO CUSTOMER(id, name) VALUES (1, 'John Doe')\")\n                                        .build();\n\n@Test\npublic void testUsingRxJdbc() throws Exception {\n    assertNotNull(dbRule.getConnection());\n    final Database database = Database.from(dbRule.getConnection());\n    assertNotNull(database.select(\"SELECT sysdate from DUAL\")\n                  .getAs(Date.class)\n                  .toBlocking()\n                  .single());\n\n    assertEquals(\"John Doe\", database.select(\"select name from customer where id=1\")\n                                     .getAs(String.class)\n                                     .toBlocking()\n                                     .single());\n}\n\n@Test\npublic void testUsingSpringJdbc() throws Exception {\n\n    final JdbcOperations jdbcOperation = new JdbcTemplate(dbRule.getDataSource());\n    final int id = 2;\n    final String customerName = \"Jane Doe\";\n\n    final int updatedRows = jdbcOperation.update(\"INSERT INTO CUSTOMER(id, name) VALUES(?,?)\", id, customerName);\n\n    assertEquals(1, updatedRows);\n    assertEquals(customerName, jdbcOperation.queryForObject(\"SELECT name from CUSTOMER where id = ?\", String.class, id));\n\n}\n\n@Test\npublic void testUsingConnectionUrl() throws Exception {\n\n    try(final Connection connection = DriverManager.getConnection(embeddedDatabaseRule.getConnectionJdbcUrl())) {\n        try(final Statement statement = connection.createStatement();\n            final ResultSet resultSet = statement.executeQuery(\"SELECT * from CUSTOMER\")\n        ) {\n            assertTrue(resultSet.next());\n        }\n    }\n\n}\n\n```\n\n#### Read initial SQL from a file resource (v \u003e= 0.5)\n```java\n@Rule\npublic final EmbeddedDatabaseRule embeddedDatabaseRule = \n                                EmbeddedDatabaseRule.builder()\n                                                       .withInitialSqlFromResource(\n                                                               \"classpath:initial.sql\")\n                                                       .build();\n\n@Test\npublic void testWithInitialSQL() throws Exception {\n    try (final Connection connection = embeddedDatabaseRule.getConnection()) {\n\n        try (final Statement statement = connection.createStatement();\n             final ResultSet resultSet = statement.executeQuery(\"SELECT * from PEOPLE\")) {\n\n             assertTrue(resultSet.next());\n        }\n\n    }\n\n}\n```\nIn the example above a \"classpath:\" URI has been used to specify the location of the SQL file. All URIs that are supported by [H2's Pluggable File System](http://www.h2database.com/html/advanced.html#file_system) is supported.\n\n#### Use Liquibase changelog to populate the test database (v \u003e= 0.6)\n```java\n@Rule\npublic final EmbeddedDatabaseRule embeddedDatabaseRule = EmbeddedDatabaseRule\n        .builder()\n        .withMode(CompatibilityMode.MSSQLServer)\n        .initializedByPlugin(LiquibaseInitializer.builder()\n                .withChangelogResource(\"example-changelog.sql\")\n                .build())\n        .build();\n\n@Test\npublic void testFindRolesInsertedByLiquibase() throws Exception {\n    try(final Connection connection = embeddedDatabaseRule.getConnection()) {\n        try(final PreparedStatement statement = connection.prepareStatement(\"Select * FROM ROLE r INNER JOIN USERROLE ur on r.ID = ur.ROLE_ID INNER JOIN USER u on ur.USER_ID = u.ID where u.NAME = ?\")) {\n            statement.setString(1, \"Ada\");\n            try(final ResultSet resultSet = statement.executeQuery()) {\n                final List\u003cString\u003e roles = new LinkedList\u003c\u003e();\n                while(resultSet.next()) {\n                    roles.add(resultSet.getString(\"name\"));\n                }\n                assertEquals(2, roles.size());\n            }\n        }\n    }\n\n}\n```\n#### Use Flyway to populate the test database (v \u003e= 1.0)\n```java\n@Rule\npublic final EmbeddedDatabaseRule embeddedDatabaseRule = \n                EmbeddedDatabaseRule.builder()\n                                 .initializedByPlugin(\n                                   new FlywayInitializer.Builder()\n                                           .withLocations(\n                                                   \"classpath:migrations/\")\n                                           .build()).build();\n\n@Test\npublic void checkMigrationsHasRun() throws Exception {\n    try (final Connection connection = embeddedDatabaseRule.getConnection();\n         final Statement statement = connection.createStatement();\n         final ResultSet resultSet = statement.executeQuery(\"SELECT * FROM USER\")) {\n        assertTrue(resultSet.next());\n    }\n}\n```\n\n#### Multiple data sources in the same test class\nIf you need more than one database instance in your test class, you should name them using the \"withName\" construct.\nIf not set the rule builder will generate the name using the name of the test class\n```java\n@Rule\npublic final EmbeddedDatabaseRule embeddedDatabaseMysqlRule =\n        EmbeddedDatabaseRule.builder().withName(\"db1\").withMode(CompatibilityMode.MySQL).build();\n\n@Rule\npublic final EmbeddedDatabaseRule embeddedDatabaseMsSqlServerRule =\n        EmbeddedDatabaseRule.builder().withName(\"db2\").withMode(CompatibilityMode.MSSQLServer).build();\n```\n## Changelog\nPlease consult the [wiki](//github.com/zapodot/embedded-db-junit/wiki/Changelog).\n\n[![Analytics](https://ga-beacon.appspot.com/UA-58568779-1/embedded-db-junit/README.md)](https://github.com/igrigorik/ga-beacon)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzapodot%2Fembedded-db-junit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzapodot%2Fembedded-db-junit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzapodot%2Fembedded-db-junit/lists"}