Quarkus custom test resources dir - java

We are using multiple source sets for tests in our project which defined in gradle like this:
sourceSets {
test {
java {
srcDir file('src/test/unit/java')
}
resources.srcDir file('src/test/unit/resources')
}
functionalTest {
java {
compileClasspath += main.output
runtimeClasspath += main.output
srcDir file('src/test/functional/java')
}
resources.srcDir file('src/test/functional/resources')
}
}
And our app properties file located here: src/test/functional/resources/application-test.yml.
Quarkus doesn't read properties from this location and seems like internally has only main and test paths hardcoded, is there a way to append custom dirs to resources resolution?
We have tried also setting a custom profile to functionalTest or functional-test but it doesn't help either:
#QuarkusTest
#TestProfile(FunctionalTestProfile.class)
class FrontendControllerTest {}
import io.quarkus.test.junit.QuarkusTestProfile;
public class FunctionalTestProfile implements QuarkusTestProfile {
public String getConfigProfile() {
return "functionalTest";
}
}

We ended up using a custom test profile for functional tests which manually takes and merges resources in same way as quarkus does it internally:
import io.quarkus.config.yaml.runtime.ApplicationYamlConfigSourceLoader;
import io.quarkus.test.junit.QuarkusTestProfile;
import io.smallrye.config.source.yaml.YamlConfigSource;
import org.eclipse.microprofile.config.spi.ConfigSource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class FunctionalTestProfile implements QuarkusTestProfile {
#Override
public Map<String, String> getConfigOverrides() {
var sources = new ApplicationYamlConfigSourceLoader.InClassPath().getConfigSources(getClass().getClassLoader());
Collections.reverse(sources);
var result = new HashMap<String, String>();
sources.stream()
.filter(YamlConfigSource.class::isInstance)
.map(ConfigSource::getProperties)
.forEach(result::putAll);
return result;
}
}
Then in test itself:
#QuarkusTest
#TestProfile(FunctionalTestProfile.class)

Related

Reverse routing in junit testing does not return the full url of the controller that is declared in a splited route file

I have the following setup:
Java Play framework version 2.8.13
sbt.version=1.3.13
routes file:
-> /v1/bar Foo.Routes
Foo.routes file:
GET /foo controllers.FooController.index(request: Request)
FooController file:
package controllers;
import play.mvc.Controller;
import play.mvc.Http.Request;
import play.mvc.Result;
public class FooController extends Controller {
public Result index(Request request) {
return ok("hello world");
}
}
FooTests file:
package test;
import static org.junit.Assert.assertEquals;
import controllers.routes;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FooTests {
private static final Logger LOG = LoggerFactory.getLogger(FooTests.class);
#Test
public void test001() {
var fooUrl = routes.FooController.index().url();
LOG.debug("fooUrl: {}", fooUrl);
assertEquals("/v1/bar/foo", fooUrl); // /foo fail
}
#Test
public void test002() {
var fooUrl = new ReverseFooController(() -> "/v1/bar").index().url();
LOG.debug("fooUrl: {}", fooUrl);
assertEquals("/v1/bar/foo", fooUrl); // ok
}
}
How can I get in my unit tests the full url (/v1/bar/foo) of the controller method ?
Reversing the controller (test001()) does not work, it returns only the path from it's containing Foo.routes file (/foo).
The only solution I found is instantiating the reverted controller (test002()), but I don't like hard coding the prefix like this. It defeats the whole purpose of reverting routes to get the url.
Can I dynamically retrieve the full url (/v1/bar/foo) of the controller inside my unit tests having this split routes strategy ?
I put the source in a repo here

Spock order tests by packages

He,everyone! My tests are running by jenkins from general package. Can I set test package in spock which will be runnning first and if in this package will not passed any of test the other tests should be skipped. I saw examples like this:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
#RunWith(Suite.class)
#Suite.SuiteClasses({TestJunit1.class, TestJunit2.class})
public class JunitTestSuite {
}
But maybe spock has solution where I can use packages instead enum of each classes, because I have many test classes in other many packages.
Also after i used runner
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(JunitTestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
The main thread doesnt stop. I dont know why.
I want to do something like that:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
#RunWith(Suite.class)
#Suite.SuiteClasses({com.example.test.*.class})
public class JunitTestSuiteFirst {
}
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
#RunWith(Suite.class)
#Suite.SuiteClasses({com.example.otherTest.*.class, com.example.otherTests2.*.class})
public class JunitTestSuiteFirst {
}
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(JunitTestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
if(result.wasSuccessful()){
JUnitCore.runClasses(JunitTestSuite.class);
}else {
System.out.println("Build failed");
}
}
}
Or maybe exist more simple solution of this task. Thanks.
Anything you can work out inside your unit testing framework isn't going to be pretty. This is because unit tests are supposed to be independent from each other, with that mindset there won't be strong support for configuring the order of tests. As such your best bet is to look for your solution in your build tools (Ant, Maven, Gradle, etc).
The following gradle snippet sets up 2 different sets/directories of unit tests. With the command gradle test integrationTest build the tests under src/integration will only run if all the tests under src/test pass.
sourceSets {
integrationTest {
java {
srcDirs = ['src/integration']
}
groovy {
srcDirs = ['src/integration']
}
resources.srcDir file('src/integration/resources')
}
test {
java {
srcDirs = ['src/test']
}
groovy {
srcDirs = ['src/test']
}
}
}

SpringBoot unit test configuration

I created a spring-boot 1.4.0 application and I would like to internationlize it using yaml file.
I created a class for loading the configuration from the yaml file like it is explained in the documentation here http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties.
I would like to create a test to check that my class has correctly loaded the properties from the yaml file.
If we keep the exemple from the documentation how to create a unit test that will load a yaml file (with a different name that application.yml) and check that the method getUsername() will return the value from the yaml file ?
Here is the code I have but still can't load the username :
#Component
#ConfigurationProperties(locations = "classpath:mylocalizedprops.yml", prefix="connection")
public class ConnectionProperties {
private String username;
// ... getters and setters
}
and the test class
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = Application.class)
public class InternationalizationTest {
#Autowired
private ConnectionProperties connectionProperties;
public void propsShouldBeNotNull() {
assertNotNull(connectionProperties);
}
public void userNameShouldBeCorrect() {
assertEquals(connectionProperties.getUsername(), expectedUserName);
}
}
I have failed the userNameShouldBeCorrect test. The file mylocalizedprops.yml is located in the src/main/resources folder of a Maven structured application.
I would consider this an integration test, not a unit-test because you are testing the interaction between various components. Regardless, here is how I would do it.
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = YourApplication.class)
public class InternationalizationTests() {
#Autowired
ConnectionProperties connectionProperties;
#Test
public void testCorrectTranslationLoaded() {
Assert.assertEquals("english-username", connectionProperties.getUsername());
}
}
You can also create a test configuration if you would like to, which you can specify which translation to load. You would then need different classes to test different configurations. See the docs: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
Unit test can be done easily with Jmockit
import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import mockit.Verifications;
class RuleApiApplicationTest {
#Mocked
private ConfigurableApplicationContext mockedContext;
#Test
void testApplicationRun() {
new MockUp<SpringApplication>() {
#Mock
public ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return mockedContext;
}
};
RuleApiApplication.main(new String[]{});
new Verifications() {{
SpringApplication.run(RuleApiApplication.class, new String[]{});
}};
}
}

How can I build Google App Enging Java SDK?

I have downloaded the source code of Google App Engine and I would like to change the behavior of some methods (for example, DatastoreService.put(Entity e)) used in this example:
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class LocalDatastoreTest {
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
#Before
public void setUp() {
helper.setUp();
}
#After
public void tearDown() {
helper.tearDown();
}
// run this test twice to prove we're not leaking any state across tests
private void doTest() {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
assertEquals(0, ds.prepare(new Query("yam")).countEntities(withLimit(10)));
ds.put(new Entity("yam"));
ds.put(new Entity("yam"));
assertEquals(2, ds.prepare(new Query("yam")).countEntities(withLimit(10)));
}
#Test
public void testInsert1() {
doTest();
}
#Test
public void testInsert2() {
doTest();
}
}
The problem is that I do not see that the build.xml file provided with the source code makes any compilation of the source .java files. For example, when I add some garbage to one of the source files and try to build the SDK using ant dist it returns BUILD SUCCESSFUL rather than a compile time error.
Any ideas where can I find the source file of the put(Entity e) method? and how can I compile the source code?
You cannot make any changes to App Engine SDK. SDK exposes methods that are directly related to and dependent upon the internal operations of the App Engine and its Datastore. You are not supposed to compile the SDK separately from your source code.

Not able to use some Junit classes properly

I want to use ErrorCollector class in jUnit but not able to import its required class.
I want to import org.junit.rule.* but instead of that i get option for importing import sun.org.mozilla.javascript.internal.ast.ErrorCollector. I do not understand what is happening. I do not get any option for importing Rule class, I tried to type import org.junit.rule but its not imported successfully.
Please help or explain me what is going on?
Thanks.
package testcases;
import junit.framework.Assert;
import org.junit.Test;
//import sun.org.mozilla.javascript.internal.ast.ErrorCollector;
public class understandingAssertion {
#Rule
public ErrorCollector er = new ErrorCollector();
#Test
public void countFriendTest() {
int actual_fr = 100; //Selenium
int expected_Fr =10;
/*
if (actual_fr == expected_Fr) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
*/
System.out.println("A");
try
{
Assert.assertEquals(expected_Fr, actual_fr);
}
catch(Throwable e)
{
System.out.println("Error encountered");
}
}
}
Your IDE will probably only give you the option to import classes that exist on your classpath.
Add the jar to your classpath and you'll be able to import the class without error.

Categories