Quarkus: clean H2 DB after every test - java

I set up a standard Quarkus project as described in the quickstart, and I'm now running multiple #QuarkusTest, using Liquibase and H2.
I noticed that between tests, the data written in H2 is preserved.
Is my project wrongly configured or does it behave like so for everyone?
Do Quarkus/H2 provide a way to automatically clean all the tables after every test execution?

I don't know if there is a way to "automatically clean all the tables after every test execution".
One workaround I'm doing is to create one class on the test package and put all the DELETEs needed there. The idea is to run this deletion method on the beginning of the tests that need clean tables.
package org.acme.tests;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
#ApplicationScoped
public class CleanTables {
#Inject
EntityManager entityManager;
#Transactional
public void clean() {
entityManager.createNativeQuery("DELETE FROM YOUR_SCHEMA.YOUR_TABLE_A").executeUpdate();
entityManager.createNativeQuery("DELETE FROM YOUR_SCHEMA.YOUR_TABLE_B").executeUpdate();
}
}

Related

ConstraintCollectors not recognized in Spring Boot (STS)

I'm trying to make use of the Optaplanner constraintprovider, which works fine until I want to use the count() ConstraintCollector.
I try to use it in a groupBy-clause, but I get the error: The method count() is undefined for the type hamxConstraintProvider
I was under the assumption this should "just work"? Or should I write my own method for count? I couldn't find that happening in the examples, but seem unable to fix it either. Am I overlooking an import?
import org.optaplanner.core.api.score.stream.Constraint;
import org.optaplanner.core.api.score.stream.ConstraintFactory;
import org.optaplanner.core.api.score.stream.ConstraintProvider;
import org.optaplanner.core.api.score.stream.uni.UniConstraintCollector;
import org.optaplanner.core.api.score.stream.bi.BiConstraintCollector;
import org.optaplanner.core.api.score.stream.ConstraintCollectors.*;
import org.optaplanner.core.api.score.stream.Joiners.*;
...
public class hamxConstraintProvider implements ConstraintProvider{
#Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[] {
skillUnavailable(constraintFactory),
balancedJobs(constraintFactory)
};
}
...
private Constraint balancedJobs(ConstraintFactory factory) {
return factory.from(Job.class)
.groupBy(Job::getEmployee,count())
.penalize("unbalancedEmployeeUsage", HardSoftScore.ONE_SOFT,count);
}
Instead of
import org.optaplanner.core.api.score.stream.ConstraintCollectors.*;
import org.optaplanner.core.api.score.stream.Joiners.*;
use static imports:
import static org.optaplanner.core.api.score.stream.ConstraintCollectors.*;
import static org.optaplanner.core.api.score.stream.Joiners.*;
The former imports classes, the latter imports static methods.
count() and countLong() are methods of ConstraintCollectors. If it compiles but doesn't run, you're likely not providing Spring's ClassLoader to the SolverConfig.
In the next release, 7.32, we're releasing optaplanner-spring-boot-starter, which will make Spring Boot integration a lot easier (it just auto injects a SolverManager (or SolverFactory, but the former is the latter on steriods)

Need to assign dynamic string value to #PactFolder annotation in Java-Pact Contract test

I need to add a variable value to a class-level annotation "#PactFolder" in a JUnit test. I've been able to achieve the dynamic assignment for this annotation using simple reflection in the #BeforeClass method.
However, This JUnit contract test runs with another annotation (#RunWith(PactRunner.class)). Now, since the #PactFolder annotation's purpose is to pass an absolute path to the PactRunner class, and PactRunner reads the value of #PactFolder at the time of invocation, the reflected variable value is of no use.
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import au.com.dius.pact.provider.junit.PactRunner;
import au.com.dius.pact.provider.junit.Provider;
import au.com.dius.pact.provider.junit.loader.PactFolder;
import au.com.dius.pact.provider.junit.loader.PactSource;
import au.com.dius.pact.provider.junit.target.HttpTarget;
import au.com.dius.pact.provider.junit.target.TestTarget;
#PactFolder("<Dynamic value>")
#RunWith(PactRunner.class)
#Provider("CvSaveDataServiceProvider")
public class ContractTest {
#BeforeClass
public static void setConditions() {
PactFolder pactFolder = ContractTest.class.getAnnotation(PactFolder.class);
AlterPactFolderAnnotation.setAbsolutePactDirectory(ContractTest.class, PactFolder.class, ContractDirectoryRelativeModulePath.HRIS.getRelativeModulePath(), pactFolder);
System.out.println(ContractTest.class.getAnnotation(PactFolder.class).value());
}
#TestTarget
public HttpTarget target = new HttpTarget(8080);
}
I need to access contracts from a locally cloned repository, kept in multiple directories, with final aim to add paths of all directories in a single config file and initialize all tests in different directories from a single point using "mvn test" command (a simple batch file)
Is there a possible solution or any workaround to do this ?

Junit test with #RunWith(PowerMockRunner.class) fails - "No tests found matching.."

I'm trying to figure out the reason of why I'm getting errors when I'm trying to run some tests that were created and did run a while back. This is the Test class:
package com.chw.pxi.impl.oneway.formatter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
public class OnewayOldFormatterTestsWhy
{
#Before
public void setUp()
{
}
#Test
public void
test_nothing()
{
System.out.println("Yep");
}
}
Here is the error when I try to run the "test_nothing" method by right-click, choose "Run As/Junit test".
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=test_nothing], {ExactMatcher:fDisplayName=test_nothing(com.chw.pxi.impl.oneway.formatter.OnewayOldFormatterTestsWhy)], {LeadingIdentifierMatcher:fClassName=com.chw.pxi.impl.oneway.formatter.OnewayOldFormatterTestsWhy,fLeadingIdentifier=test_nothing]] from org.junit.internal.requests.ClassRequest#3632be31
at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:40)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createFilteredTest(JUnit4TestLoader.java:77)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:68)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
There are lots of jar files in the build path for this project. I guess I should try creating a new project and see if the problem follows. A side note - when I run a test on a method in another test that has this - it runs fine without the error above:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"dao-tests-context.xml"})
#TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
//Note: This is a live database test but transactions will be rolled back
//except those that invoke methods that require new transactions
public class AgencyDaoTests
If there is additional information needed, please let me know what and how I can go about and get that information for you.
Thanks, Michael
As for 'org.powermock:powermock-api-mockito2:1.6.5' version of Powermock I managed this to work by moving #PrepareForTest annotation from method level to class level.

Play Framework 2.0 and EBean, wrapping INFORMATION_SCHEMA

Using Play! Framework 2.0.4 and EBean as the persistence layer I am attempting to wrap a databases "meta" information to Java classes.
I map the classes in application.conf:
db.myData.url="jdbc:sqlserver://localhost:2301;databaseName=myData;"
ebean.myData="models.database.JavaTable"
I then created a class as follows:
package models.database;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import play.db.ebean.Model;
#Entity
#Table(name="tables",schema="INFORMATION_SCHEMA",catalog="myData")
public class JavaTable extends Model{
#Column(name="TABLE_NAME")
public String table_name;
public static Finder<String, JavaTable> find = new Finder<String, JavaTable>(
String.class, JavaTable.class
);
}
When I fire up Play!, it tells me that I need to run an evolution on the database to create the table "myData.INFORMATION_SCHEMA.tables". I then tried to test the connection via a unit test...
#Test
public void testGetTables(){
running(fakeApplication(), new Runnable() {
#Override
public void run() {
EbeanServer server = Ebean.getServer("myData");
List<SqlRow> rows = server.createSqlQuery("select * from myData.Information_Schema.Tables").findList();
for(SqlRow row: rows)
System.out.println("====>Row: " + row.toString());
}
});
}
The unit test executes correctly and the table names are printed out successfully.
Edit: per #nico_ekito I removed the evolution plugin in the configuration file and started getting:
RuntimeException DataSource user is null
So, researching a bit I decided to disable other datasources in the config file and moved the database I'm attempting to communicate with to "db.default" and "ebean.default" and the models started working. Is there a way to tell a model which datasource it should use if Play has multiple databases defined? Setting the classes via "ebean.default="myData.JavaTable" did not seem to work.
You should try to disable the evolutions by adding the following in your application.conf file:
evolutionplugin=disabled
The tests are ok because since you're not starting a real application, but using a fakeApplication() which does not use the evolutions plugin.
Anecdotally, I've only had success defining my eBean server using package level values (so, "myData.*" instead of "myData.JavaTable"). To pull this off, you may have to move all classes for a particular eBean server to their own package.

Is it possible to run JUnit tests from multiple packages in Eclipse?

Is it possible to run JUnit tests for multiple packages at the same time without manually creating test suites.
For example if I have the hierarchy:
code.branchone
code.branchone.aaa
code.branchone.bbb
code.branchtwo
code.branchtwo.aaa
code.branchtwo.bbb
Is it possible to:
Run all tests in code.branchone and in descendent packages
Run all tests in say code.branchone.aaa and code.branchtwo.bbb
The problem I see with manually creating test suites is that when new tests come along you may forget to add them.
Yes, it is possible. The easiest way for me at least is to add a test suite class. It can look like this:
package tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import tests.message.ATest;
import tests.validator.BTest;
import tests.validator.CTest;
import tests.validator.DTest;
#RunWith(Suite.class)
#SuiteClasses({ ATest.class,
BTest.class,
CTest.class,
DTest.class })
public class AllTests {
}
This will allow you to test any class that you import no matter what package it is in. To run this in eclipse you just right click the AllTests class and run it as JUnit test. It will then run all the tests you define in #SuiteClasses.
This will work with linked sources as well, I use it all the time.
An other way:
Click on the black triangle denoted by red rectangle in the picture below (in your Eclipse, not here :).)
Then open run configurations, create a new configuration and then set "Run all tests..." as exemplified in the image below.
Maybe not exactly what the original question was, but you can easily run all tests of a whole Project, by simply right-clicking the project -> Run As JUnitTest. Don't worry where the annotated classes reside, this will be scanned.
This does not work if applied to the test-src-folder or a package with subpackes. Quite a shame actually -.-
I'm sure u can tweak this a bit. Make a Collection of the CLASSES_DIR property and loop over it in the findClasses method. (junit4)
http://burtbeckwith.com/blog/?p=52
I beleieve that you can add all your test packages to a single directory. If you right click on this directory, then you should find the "run as -> JUnit test" option available. This will run all tests contained in the directory and will catch anything you've added. Any new tests get put in there with the rest of them and whatever package name you have it doesn't matter. Hope that helps
Sure, right-click on the packages you want, and select Run As... JUnit Test
In Eclipse, on your debug/run configurations you have the following options:
Run a single test
Run all tests in the selected project, package or source folder
I think the second option is your friend in this case.
If you are using JUnit 5 you can cherry pick which tests you want to run:
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import tests.Test1;
import tests.Test2;
import tests.Test3;
#Suite
#SelectClasses({
Test1.class,
Test2.class,
Test3.class
})
public class AllMyTests {
}
If you want to select which packages to run you can:
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
#Suite
#SelectPackages({
"com.package1",
"com.package2",
"com.package3"
})
public class AllMyTests {
}
If you need to be able to exclude certain sub-packages you can do:
import org.junit.platform.suite.api.ExcludePackages;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
#Suite
#SelectPackages({
"com.package1",
"com.package2",
"com.package3"
})
#ExcludePackages({
"com.package1.subpackage",
"com.package2.othersubpackage"
})
public class AllMyTests {
}
Other useful annotations:
To match a particular pattern:
#IncludeClassNamePatterns({"^.*ATests?$"})
To exclude a particular pattern:
#ExcludeClassNamePatterns({"^.*ATests?$"})
Examples were based on: https://howtodoinjava.com/junit5/junit5-test-suites-examples/

Categories