Spring boot integration test with environment variables - java

I'm working on a multi-module maven project using Java 8, Spring Boot 2.4.0. I want to test one of a module that is calling a 3rd party service. I'm using wiremock to mock that 3rd party service call and have created a spring boot integration test class. My class is in the same package where my XYZService class is. My test is in src/test/... and looks like this.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SpringApplicationClassWithMainMethod.class)
public class XYZServiceIntegrationTest {
#Rule
public WireMockRule externalService = new WireMockRule();
#Test
public void test1() {...}
#Test
public void test2() {...}
}
When I run the maven build in my eclipse (clean + install). My build is not detecting the tests present at the maven-module where the Integration test is located. The other unit tests in the same module are also not being detected (Note: before adding the integration test class, the unit tests were working). Maven says Tests ran: 0. The integration test is working fine when I Right click on the file and run as JUnit test(Junit 4). Also, I have some environment variables that need to be set for running the SpringApplicationClassWithMainMethod.class that I'm setting within the configurations of that Integration test class in order to successfully load the Application context(I tried to load the environment variables through code and nothing from other stack-overflow posts worked). One more thing to inform my maven only uses Maven surefire plugin for running tests. I dont know if we need to have Maven fail safe plugin for my purpose(Is my test considered a Integration Test when I added the 2 annotations on top of the test class?). Can someone please help me with any suggestions on how to build the parent project.

Adding the maven-failsafe-plugin into my child pom worked. In the parent pom I added the execution goals for maven-failsafe-plugin in the and in the child pom I inherited that plugin.

Related

Disable spring boot all together when running maven test

I have some unit test classes in my project that I want to test with mvn test. But whenever I run the command an instance of spring boot starts and opens database connections.
I´m running these tests in a server that doesn´t have access to a database, and none of my tests uses one. I just one to execute the tests as the IDE does.
I think one of them could help you
1 - Disable all tests
mvn clean install -DskipTests
2 - Prepare your test for switching
#ExtendWith(SpringExtension.class)
#EnabledIf(expression = "${tests.spring.enabled:true}")
if you pass -Dtests.spring.enabled= false or true will disable test
3 - Point your test to other configuration
#ExtendWith(SpringExtension.class)
#TestPropertySource(locations = "classpath:application-${spring.profiles.active:test}.properties")
this way you could connect your application into a local database
4 - Change your tests
Use mocks to turn your integration tests into a unit tests or component tests with no connections
The problem I had was an empty class with #SpringBootTest annotation. After deleting it the tests works without spring interfering.

Can I run a JUnit4 test suite by using specified maven goal only?

I am looking for a way of running a specified package of tests only when a specified maven goal is runned.
lets say that I have a
package com.myapp.test;
It is containing some standard JUnit tests, and I want those tests to be runned everytime someone is building the app locally or on any other environment (dev/test/preprod etc.) running mvn clean package
And I have a
package com.myapp.test.integration;
Which is containing integration tests. Every single test is extending AbstractTransactionalJUnit4SpringContextTests
I have created a suite:
#ContextConfiguration(classes = DbUnitApplication.class) // this is the main Spring class, nothing special
#Persistent
#RunWith(WildcardPatternSuite.class)
#SuiteClasses("**/*Test.class")
public class DbUnitTestSuite {
}
and it is running the tests properly (the integration tests only, which is the expected behaviour). But what can I do to make them run when some command like this is runned:
mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Pcitest -Pdbunit -Ddbunit.spring.datasource.url=jdbc:mysql://localhost:3306/mydb
How can achieve it? Can I do it using some other way? This given command is a legacy before we have migrated from TestNG to JUnit4, and BEFORE we started the migration, all this looked a bit different, with an pom.xml entry:
<profiles>
<profile>
<id>dbunit</id>
<properties>
<dbunit.run.liquibase>true</dbunit.run.liquibase>
<dbunit.skipped.group></dbunit.skipped.group>
</properties>
</profile>
</profiles>
And a class:
#ContextConfiguration(classes = DbUnitApplication.class)
#Test(groups = "dbunit") // IMPORTANT - this is TestNG's #Test annotation, NOT JUnit
public class DbunitTestParent extends AbstractTransactionalTestNGSpringContextTests {
#PersistenceContext
private EntityManager em;
#AfterMethod
public final void flush() {
em.flush();
}
}
And every single integration test extended this DbunitTestParent class.
Do You have any advice how to achieve it? How to skip those integration tests in a normal mvn clean package build, but somehow run them with a maven goal or another CLI parameters?

Cucumber tests not running Liquibase

Liquibase does not run when I execute my Cucumber tests, although works fine for application and unit tests.
I have a suite of cucumber-spring tests, testing a spring-boot application.
I have recently introduced Liquibase to the application, which runs fine when I run the application or the unit tests, but does not get run when I run my cucumber tests, either from a RunCukesTest Junit class or from the cucumber-cli.
The correct application.properties files get loaded in all cases, and I do nothing special to get Liquibase to run in the standard application and tests. It is enabled by default, and I have tried forcing enabled, but with no luck.
I have tried setting a SpringLiquibase bean in the tests, but cucumber-spring does not like this, as it does not allow further #Configuration classes.
The Liquibase jar is available on the classpath, and referencing a Liquibase type compiles fine in the cucumber steps.
The only property I set is :
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml
My Cucumber test class has the signature:
#Ignore
#SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class SpringConfig extends SpringBootBaseIntegrationTest implements En {
in application.properties. I have tried setting this for Cucumber application.properties also with no change.
Liquibase should run my changelog files as per standard application launch.

Spring integration test module running app from separate module without properties for DB config

Given a spring boot gradle module named "md-core" with a Spring application runner and a PostgresDbConfig to connect it to the DB.
The app runs perfectly fine and resolves the properties from the "application.yml" file in the #Config.
#Value("${db.default.pool.size}")
Integer maxPoolSize;
Now, a separate module called "integrationtests" tries to launch the Spring Boot Runner in the "md-core" module.
#ContextConfiguration(classes = {MdCore.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class GivenTest
The test launches the "md-core" Spring runner, but when trying to resolve the properties in the #Config, it does not find any properties.
I've tried directly resolving the "application.yml" in the test. It does not send the properties over to the "md-core" module. Any attempt of adding the "application.yml" properties in the test resolves them to the test file, but does not send them over when the "md-core" module is accessed.
Are there any definitions which should be given in the test via annotations or in the gradle build files?
The classpath when launching the test does not contain the "md-core" resources location, only the classes.
Could this be a reason? If yes, how can the resources be referenced in the classpath of the gradle build files?
I apologize for any mistakes or incomplete information, this post is being written at the end of a work day, hoping there will be answers by morning.
Given this situation, the solution to use the application.properties file for the integration test is the simple addition of initializers = ConfigFileApplicationContextInitializer.class in the #ContextConfiguration annotation of the Test class:
#ContextConfiguration(
initializers = ConfigFileApplicationContextInitializer.class,
classes = {SomeApp.class})
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
public class SomeIntegrationTest {
#Test
public void testTheIntegration() {
// some integration tests here
}
}
Answer also documented in a post on my blog and initially found less detailed on another stackoverflow question.

How do I configure arquillian suite extension

How do I configure Arquillian Suite extesion?
https://github.com/it-crowd/arquillian-suite-extension
I would like to use it for single deployment tests, in order not to have to deploy for every single class that have #Test methods in my project.
By the way, I'm using TESTNG with arquillian..
I pushed extension bit further, it can be found on maven central and there is part of help written + tests to look how it should be done.
I also created "generic" deployer builder that should work with javaee6.
https://github.com/ingwarsw/arquillian-suite-extension

Categories

Resources