dadrus / jpa-unit Goto Github PK
View Code? Open in Web Editor NEWJUnit extension to test javax.persistence entities
License: Apache License 2.0
JUnit extension to test javax.persistence entities
License: Apache License 2.0
Cucumber is a framework for BDD testing
Implement an extension to JPA-Unit which supports all the JPA-Unit tools with Cassandra.
The idea is to be able to use JPA providers, which support NoSQL databases, thus to be able to reuse (to a certain extent) existing code and test implementation when switching between different data base types or when using different types of data bases (polyglot persistence) in one project.
Cassandra seems to be supported by following JPA provider:
The funcionality to seed the database using db specific scripts and statement is already available. It would be however very helpful if direct usage of domain objects would be possible to seed the db in a test case aware setup phase (like available with db statements and scripts) which runs in its own transaction.
It should be possible to arbitrary define the required domain object, e.g by the use of such libraries like benas/random-beans or test-data-loader and in best case having all phases as defined by @InitialDataSets
Usually one would like to run specific JPA tests using an in-memory database to have a clean entry point. Executing tests of a single test class will not reveal any limitations of this approach. However running multiple test classes in a batch, like done in CI environments or by just typing mvn test
might expose an unexpected limitation: a database (schema and contents) from the execution of a previous test class might still be there and interfere with the execution of the current test class. This is mainly related to when an in-memory database is removed. Most vendors do this when the last connection to the database is closed. Since JPA provider implement and rely on connection pooling, additional time is required to close these connections after closing of the EntityManagerFactory
instance. This limitation can only occur if no database cleanup is done by the preceding test class or during the bootstrapping of the current test class.
Here some examples which also describe possible workarounds:
@Cleanup
is disabled) the database contents. In such case one should add the @Cleanup
annotation to the last method (consider the execution order of the test methods) of that test class or clear the database contents in the bootstrapping method.Concordion is a framework for BDD testing
Currently a glue implementation have to take care of the db cleanup by itself by placing @Cleanup
annotation on an appropriate method. Automatic cleanup, like available with regular JUnit tests, should be possible as well.
Flyway (https://flywaydb.org) is a lightweight DB versioning and migration tool which uses plain java or SQL to setup/migrate the DB schema or DB contents. Adding support for both types would give more added value to the test de tension.
Looks like the bom descriptor includes invalid dependencies. Lines pom.xml#L19 and pom.xml#L24 should not be jpa-unit-junitX
but just jpa-unitX
.
No artifact found for jpa-unit-junit4 but I can spot jpa-unit4.
Also note that using maven macro functions <groupId>${project.groupId}</groupId>
and <version>${project.version}</version>
in your bom will not always populate these fields with the values of your bom but with values of the importing project. It's a known issue and folks typically generate their bom without maven macro functions.
Liquibase (http://www.liquibase.org) is a powerful tool which enables versioning control for the DB schema and contents. Adding support for it would give more added value to the test extension.
As of today the jpa-unit cdi-extension handles CDI Producer only. That is, the jpa-unit cdi-extension cannot cope with situations, where the code under test injects EntityManaget
or EntityManagetFactory
directly (by using e.g. @PersistenceContext
annotation). In such situation the developer has to inject the EntityManaget
or EntityManagetFactory
created by the jpa-unit by hand (e.g. by using a corresponding setter or reflection) in the test setup method. The jpa-unit cdi-extension is even not needed in such cases. It would be however helpful, if the cdi-extension would support such cases as well, thus eliminating the need of manual setup.
It would help a lot if a release can be built and published by just pushing to the release branch. Here the corresponding script should perform following steps:
revision
value from the top level pom.xml
release
profile and by setting the revision
parameter to the read value from 2 without the -SNAPSHOT
suffix.v
prefix and without the -SNAPSHOT
suffix. Otherwise fail.revision
property in the pom.xml
.Implement an extension to JPA-Unit which supports all the JPA-Unit tools with MongoDB.
The idea is to be able to use JPA providers, which support NoSQL databases, thus to be able to reuse (to a certain extent) existing code and test implementation when switching between different data base types or when using different types of data bases (polyglot persistence) in one project.
Implement an extension to JPA-Unit which supports all the JPA-Unit tools with Neo4J.
The idea is to be able to use JPA providers, which support NoSQL databases, thus to be able to reuse (to a certain extent) existing code and test implementation when switching between different data base types or when using different types of data bases (polyglot persistence) in one project.
As of today the data sets are loaded again and again during the execution of each test method. To improve performance the data sets should be loaded only if the were not used before or have changed (e. g during debugging) between the executions of test cases/methods.
Implement an extension to JPA-Unit which supports all the JPA-Unit tools with Infinispan.
The idea is to be able to use JPA providers, which support NoSQL databases, thus to be able to reuse (to a certain extent) existing code and test implementation when switching between different data base types or when using different types of data bases (polyglot persistence) in one project.
JUnit 5 is the next generation of JUnit.
javax.persistence.jdbc.user
and javax.persistence.jdbc.password
are not always required to be configured. Some rdbms support setting of user and password as part of the jdbc url. In such cases the jpa-unit rdbms extension cannot be used. It simply ignores the persistence.xml
configuration und thus is not executed.
The solution is simple: just delete the verification of the presence of the both aforesaid properties in the `persistence.xml'.
As a workaround for the test code affected by this issue (as long as the fix is not avalable), configure the aforesaid properties and remove corresponding settings from the jdbc url.
Currently a fixture implementation have to take care of the db cleanup by itself by placing @Cleanup
annotation on an appropriate method. Automatic cleanup, like available with regular JUnit tests, should be possible as well.
Hi,
it's more a question than an issue. Or maybe both. I like your Junit5 extension and just wanted to integrate it into one of my projects. I didn't find a proper way to setup the database connection dynamically while startup time instead of configure it in persistence.xml. This is the best way I found:
@PersistenceContext(unitName = "test-unit")
private` EntityManagerFactory emf;
@BeforeEach
void before() {
Map<String, Object> p = emf.getProperties();
p.put("javax.persistence.jdbc.url", System.getProperty("javax.persistence.jdbc.url"));
p.put("javax.persistence.jdbc.user", System.getProperty("javax.persistence.jdbc.user"));
p.put("javax.persistence.jdbc.password", System.getProperty("javax.persistence.jdbc.password"));
}
Is there a more proper solution?
Thanks,
Mike
Project Jigsaw should finally make it into official Java, but might lead to a lot of surprises.
My persistence.xml looks like
<persistence-unit name="..." transaction-type="JTA">
<jta-data-source>...</jta-data-source>
In the test I want to override it with RESOURCE_LOCAL. At least in Hibernate this can be done by setting the following properties:
Map<String, Object> persistenceProperties = new HashMap<>();
persistenceProperties.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
persistenceProperties.put("javax.persistence.jtaDataSource", null);
persistenceProperties.put("javax.persistence.jdbc.url", "...");
...
EntityManagerFactory emf = Persistence.createEntityManagerFactory(..., persistenceProperties);
I want to achieve the same behavior with @PersistenceProperty, but I cannot set the jtaDataSource to null, which is essential (at least for Hibernate).
My proposal is to set the "javax.persistence.jtaDataSource" property value to null, if it is present in the properties and is an empty string. This way, it could be removed by providing an empty string.
@PersistenceContext(unitName = "...", , properties = {
@PersistenceProperty(name = "javax.persistence.transactionType", value = "RESOURCE_LOCAL"),
@PersistenceProperty(name = "javax.persistence.jtaDataSource", value = ""),
...})
private EntityManager entityManager;
Having the supported data set formats defined on the top level hinders the independent evolution of db specific plugins. So move the corresponding implementation to the specific plugins and let them implement their supported formats independently.
Implement an extension to JPA-Unit which supports all the JPA-Unit tools with CouchDB.
The idea is to be able to use JPA providers, which support NoSQL databases, thus to be able to reuse (to a certain extent) existing code and test implementation when switching between different data base types or when using different types of data bases (polyglot persistence) in one project.
CouchDB seems to be supported by following JPA provider:
Implement an extension to JPA-Unit which supports all the JPA-Unit tools with Redis.
The idea is to be able to use JPA providers, which support NoSQL databases, thus to be able to reuse (to a certain extent) existing code and test implementation when switching between different data base types or when using different types of data bases (polyglot persistence) in one project.
The test extension currently supports JPA 2.1 only. To give more value to it, JPA 2.0 should be supported as well.
As of today the implementation of @ExpectedDataSets
fully relies on the comparison implementation provided by DbUnit. DbUnit however imposes a restriction: adding a new row to a table which is referenced by the expected data set but not included in it, will lead to a comparison error.
The aforementioned behavior contradicts the database bootstrapping approach. Here one would usually not only want to create the database schema, but also some initial data, which might be extended/modified by the implemented test methods. For this a further cleanup strategy might be required.
When I run the following code I would expect that the database is always cleared after each test and so the results of test1()
and test2()
would be the same. However test2()
returns two elements instead of the expected 1.
@ExtendWith(JpaUnit.class)
class CleanupTest {
@PersistenceContext(unitName = "my-test-unit")
private EntityManager entityManager;
@BeforeEach
void setup() {
Test t1 = new Test();
t1.setName("Test1");
entityManager.persist(t1);
}
@Test
void test1() {
List list = entityManager.createQuery("select t from Test t").getResultList();
System.out.println(list.size()); // 1
}
@Test
void test2() {
List list = entityManager.createQuery("select t from Test t").getResultList();
System.out.println(list.size()); // 2
}
}
Is there anything that I'm missing here? I tried with several combinations of the @Cleanup
and @Transactional
annotations at class and method level, but the result was always the same.
Adding a new row to a table which is referenced by the expected data set but is not included in it (or vice versa) will lead to a comparison error. A possibility to filter such entries is helpful.
The implementation does not take into account, that the behavior of EntityManager.getProperties(), respectively EntityManagerFactory.getProperties() is not defined by neither the JPA 2.0, nor by JPA 2.1 standard. Thus it is JPA provider dependent, which key-value pairs are returned. Because of this, the current implementation seems to support EclipseLink only. At least Hibernate can not be used as a JPA provider. This provider does not return the properties defined in the persistent unit as they are defined.
Instead of relying on the values returned by the JPA provider, the extension should perform a lookup of the required persistence.xml
definition and read the relevant settings from there.
By adding this extension to the classpath, it should be possible to run the JPA Unit tests without adding definitions for JpaUnitRunner
or JpaUnitRule
.
Hello,
is it possible to set dbunit properties for example "http://www.dbunit.org/features/qualifiedTableNames"?
How can i set the schema?
cheers,
attrobit
When I try to access a global EntityManager instance from @nested classes I get the following exception:
java.lang.IllegalArgumentException: JPA test must have either EntityManagerFactory or EntityManager field annotated with @PersistenceUnit, respectively @PersistenceContext
My class looks like this:
@ExtendWith(JpaUnit.class)
class NestedTest {
@PersistenceContext(unitName = "my-test-unit")
private EntityManager entityManager;
@Nested
@DisplayName("Given an empty test table")
class GivenAnEmptyTestTable {
@Test
@DisplayName("Then the size sould be zero")
void thenTheSizeShouldBeZero() {
List<Test> list = entityManager
.createQuery("select t from Test t", Test.class)
.getResultList();
assertEquals(list.size(), 0);
}
@Nested
@DisplayName("When a row is inserted")
class WhenARowIsInserted {
@BeforeEach
@Transactional(TransactionMode.COMMIT)
void setUp() {
Test t = new Test(1, 2, 3);
entityManager.persist(t);
}
@Test
@DisplayName("Then the size should be one")
void thenTheSizeShouldBeOne() {
List<Test> list = entityManager
.createQuery("select t from Test t", Test.class)
.getResultList();
assertEquals(list.size(), 0);
}
}
}
}
Is it somehow possible to keep the entityManager instance in the nested tests?
As of today external PRs fail to upload analysis results to SonarCloud (due to missing credentials), which effectively leads to failed builds in Travis CI and does not allow for automatic verification of work being done.
EntityManager instance may change from one test to another test. But is also can remain the same (e.g. if EXTENDED
persistence context type is used). The first case is not covered by the current implementation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.