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
Related
Small question regarding a Spring profile (integration) applied to Springboot please.
Currently, under src/main/resources, I have several application.properties files.
Such as:
application properties
application-local.properties
application-production.properties
application-integration.prorperties
And under the src/test/resources, no properties file.
When I run maven, maven will trigger some unit and integration tests. The unit test does not need any particular profile (properties are set in the unit tests, anyway, it is not the question).
The integration tests, they need the application-integration.properties.
And currently, with the file under src/main/resources, everything is fine.
I just tried moving the file to src/test/resources, and the integration tests could not find any property, as if the file disappeared.
What is the proper way to tell Springboot to run integration tests with a application-integration.properties under src/test/resrouces please?
Thank you
You can use the below configuration for the Integration tests
#TestPropertySource(locations = "classpath:application-integration.properties")
#ActiveProfiles("integration")
I try to test my spring boot application via JUnit 5.
The test methods need some environment variables. Even I put them on the list, each test method creates a new JUnit config so I have to put them again.
I saw the document on JetBrains.
I can not save the JUnit config. because each config. depends on the method.
Is there any way to create a permanent JUnit config. on IntelliJ?
You may edit the Junit run configuration in the "Run configuration templates for new projects":
This is a bad idea. Setting up your environment variables in something like IntelliJ will make this unportable or unrunnable in a Jenkins environment.
Because you're using Spring Boot, you have more flexibility than you realize. Rework your code so that the environment variables can be injected in through application properties. Then, you can add the application properties to your test through the #SpringBootTest annotation.
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
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 am trying to figure out whether I can load the same .yml property files in testing environment as I load in real.
For example I have a test:
\src\test\java\security\TokenTest.java
Annotated with:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
#ActiveProfiles("dev")
Then I have:
\src\main\resources\application.yml
When I run the application, the environment picks up property-source from the yml location.
Whenever I run my test, the environment does not see this file - i.e. property-source is not created/populated.
The obvious solution is to put duplicate file to the test location:
\src\test\resources\application.yml
And it will load, but that is bad - in terms that it raises unnecessary confusion when perceiving the difference between test and main resources.
This previous problem gets enhanced if you have configuration file per environment.
Is there a way to load resources from src/main/resources for tests?
This is probably some basic classpath scanning concept which I don't know.
My case is that I already faced the nightmare when you have 5 yml properties files per enviornment in src/main/resources and then you have 5 corresponding yml properties files in src/test/resources and someone from your team WILL 100 % at some point introduce discrepancy between them making everyone else bleed in the long term.
So by any means tests must refer to the same configuration files not to be the lost within its own void context.
Solution: Try to "rebuild" the project.
Is there a way to load resources from src/main/resources for tests?
It works for me. Maybe your IDE is not copying changes to the output directory on save or something (I have heard IntelliJ users have to switch that feature on)?
I had the same problem as you, but I figured out that it was a classpath problem in my run configuration in intellij, when setting that up like it should have been it worked as a charm loading application.yml from the main/resources.