In my application.properties I have
quarkus.http.root-path=/my-service/api/v2
and it works when I run the app and hit the url. (It reads the config on start).
But when I run it from the test:
#QuarkusTest
#Tag("integration")
public class MyResourceTest {
#Test
public void testMyEndpoint() {
given()
.when().get("/my-service/api/v2/init")
.then()
.statusCode(200)
.body(is("{}"));
}
I got 404. But it works if do get("/init")
Seems that the Test does not know about the application.properties.
I tried to put application.properties to test/resources folder (similar to what I would do if work with Spring Bootstrap app)
I tried this, assuming it uses the test profile when I run test (did not work):
%test.quarkus.http.root-path=/my-service/api/v2
UPDATE:
I was able to read my database config though, adding %test to the test/resources/application.properties
#test
%test.quarkus.datasource.url=vertx-reactive:postgresql://mydb-url:5432/mydb
But the quarkus.http.root seems different thing.
Question is:
how to read quarkus.http.root from properties files for from the integration test? (could not find it in the doc).
This is because the Restassured integration is aware of the modified root path, so it transparently adjusts the requests it sends. When you request /init it will automatically map to /my-service/api/v2/init
Related
In my Spring Boot program I'm getting a failure due to a bad property value on load. In particular, it uses the DB2 hibernate dialect but it's not defined in the property file I thought I was using.
Assuming no annotations, where does Spring look for the properties file? Yes I know it normally resides in src/main/resources/application.properties
What if I have a property in my test cases; does it ignore the one in main and use the one in test? Or does it start with the main version and let the test one override the main where it applies?
Does the application profile affect the property file used? Some people use the same application.properties file name in both main and test.
If I do have a TestSource annotation with a class path location, does it still augment it with something somewhere else?
Finally, how can I get Spring to tell me everywhere it looked for properties and not just one of them?
#Woodsman
It's possible to use many settings in each profile/environment in spring application on src/main/resources/ folder
application-dev.properties
application-local.properties
application-onlytests.properties
application-prd.properties
application.properties
the name after hyphen will be the name profile got by spring
Ex: application-{myenviroment}.properties
When you start spring application will be used application.properties by default.
You can tell spring to use an specific properties passing the environment in one of ways below:
Putting spring.profiles.active=prd inside application.properties file
Passing by parameters when start spring app --spring.profiles.active=local
Running your jar on command line java -jar myjar.jar --spring.profiles.active=dev
Setting an environment var in your machine/docker/container SET SPRING_ACTIVES_PROFILE=local
There are other ways using annotations on beans, passing jvm arguments and others
If you need run your tests in a specific configuration ( vars, database, settings ), It's possible to pass which .properties will be used
#ExtendWith(SpringExtension.class)
#AutoConfigureMockMvc
#SpringBootTest
#TestPropertySource(locations = "classpath:application-onlytests.properties")
public class RunTest_from_onlytests_properties {
#Autowired
private MockMvc mockMvc;
#Test // org.junit.jupiter.api.Test
public void test() throws Exception{
// ...
}
}
I've started to learn Spring Boot in version 2.1.0 and I made a simple application Controller->Service->Repository->Database(H2). Very, very simple application just to start with Spring Boot.
I've read that in that framework I can add under src/resources a file data.sql where I can define insert/update etc. and after run my application that data will be stored. Everything works ok, but when I wanted to write test for my service, just to check if my repository works ok (I test DB for learning purpose) I see that while I run my test in my DB there are already values from data.sql, but I don't have data.sql under test folder. It is under src.
Maybe someone knows, how to configure project that not to take this data.sql from src/resources? Is it possible? Maybe I have to add some more annotations?
**** EDIT ****
This is my repo:
You can create test application-test.properties in test/resources
and override in in test like this:
#RunWith(SpringRunner.class)
#SpringApplicationConfiguration(classes = ExampleApplication.class)
#TestPropertySource(locations="classpath:test.properties")
public class ExampleApplicationTests {
}
Then in you new created application-test.properties file block running your script:
spring.datasource.initialization-mode=never
I develop web app with Spring Boot. I have problem with unit test for web layer.
For these tests I'm using annotation #WebMvcTest. Problem is that my main configuration class contains #PropertySource with java arg, which contains path to external properties file, and when I start my unit web test, error is occured that this java arg can't be parsed(of course I can add this java arg to run configuration of my test, but my web unit tests don't need this file).
My main config class:
#SpringBootApplication
#PropertySource(value = {"${pathto.configfile}"})
#EnableAspectJAutoProxy
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My first solution was to create separate configuration class with "!test" profile, and relocate #PropertySource("..") to it. And to my unit test add #ActiveProfiles("test")
My second Configuration class:
#Configuration
#Profile({"!test"})
#PropertySource(value = {"${pathto.configfile}"})
public class PropertyConfiguration {
}
For unit web test this solution works very good. But new problem appears in starting of my web app. In my external properties file I have
property spring.profiles.active. To this property I assign or db or file value. Depending on its value, apropriate implementation of Repository is created and injected to my service layer. When value is db, app starts good,
but when value is file error is being thrown: NoSuchBeanDefinitionException.
When I come back to my previous version(without second configuration file), app starts good in both cases(but not web unit tests)
So, explain please, why when value of spring.profiles.active=db, app starts good, but when spring.profiles.active=file- failed.And how I can solve my task?
I attempted to find how I can add other application context to my web unit tests, but I didn't find.
Any idea?:)
For my database repositories I'm using Spring Data JPA, so I don't create implementation of these repositories, but I create implementations of my file
repositories, and my implementations had #Profile("file"). After deleting this annotation from implementations, it leaved only on interfaces. I don't know why one config class worked, but two classes didn't. But problem is solved)
I'm using JUnit to test my application and everything works fine as long as the database has been initialised before the testing (using gradle bootRun to run as a web-app). However, if the database is empty, the application does not seem to initialise any models or entities before testing. Is there a way I'm supposed to do this? I made an assumption that the ApplicationRunner class will be ran before the test and initalise the entities. Is there a way to do this or am I using the wrong approach?
This is how my application.properties file is looking like:
server.port=8090
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=123456
server.ssl.key-password 123456
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.naming-strategy:org.hibernate.cfg.ImprovedNamingStrategy
application.logger.org.springframework=INFO
My database is stored in /src/main/java/application/persistence/DbConfig.java using a DriverManagerDataSource connection. And I have setup ApplicationRunner to run add a few rows to the db upon starting.
edit:
I should also add that these are the annotations I'm using on the JUnit test file:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes={
AdeyTrackApplication.class,
SecurityConfig.class,
WebConfig.class,
AuthorizationController.class
})
There are various options if you do not want to execute that explicitly from #Before JUnit hook.
Use Spring Boot's JDBC initialization feature, where you would place schema.sql or data.sql into src/test/resources folder, so that it would be picked up only during testing.
Use Spring's #Sql annotation
You can use #Sql annotaion for populate your DB, for example^
#Sql(scripts = "classpath:db/populateDB.sql")
The above answers all use the .sql schema loading technique where I'd have to have a .sql schema for tests. I didn't want to do it that way as my schema would be expanding and I'd rather not go through the hassle of adding entries to the schema as my tests expand.
As I'm using Spring Boot, I came across this annotation which seems to solve the issue by first running bootRun and then running the tests.
In my test annotations I replaced the #ContextConfigurations with #SpringApplicationConfiguration and left all the classes to be the same. This seemed to solve the issue. So now the test task invokes bootRun to load the classes and then runs the tests.
See #SpringApplicationConfiguration
Hop this helps anyone facing the same issue.
I have an integration test set up like:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {XmlFileSplitter.class, ...})
public class XmlFileSplitterTests { ..
In the XmlFileSplitter I have a property that is annotated with #Value("${default.output.file}") and its value is retrieved from the application.properties. This works fine when running the app normally. However when running the integration test, the value is not resolved (it is "${default.output.file}").
When i debugged through the code for resolving the placeholder i noticed the org.springframework.beans.factory.support.AbstractBeanFactory embeddedValueResolvers was empty in the test, while containing a PropertySourcesPlaceholderConfigurer when running the app normally.
I saw the normal run has PropertyPlaceholderAutoConfiguration from spring-boot-autoconfigure to configure the propertyplaceholder and i figured i needed to add this class to the SpringApplicationConfiguration classes to have it configured for the integration test. I added it:
#SpringApplicationConfiguration(classes = {XmlFileSplitter.class, ... , PropertyPlaceholderAutoConfiguration.class})
and it now indeeds resolves the #Value annotation (with value from application.properties).
However this feels wrong, adding knowledge of this class to my test. My question is how to solve this properly?