Ignore component scan when all tests are ignored - java

Is there a way to ignore component scan when all tests are ignored ?
Let's say I have test like this and all tests in class are ignored
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {TestConfig.class})
#WebAppConfiguration
public class ReqMigration {
//.... all tests are ignored
}
TestConfig.class looks like this
#Configuration
#PropertySource(value = "file:${path.app}/configuration/env.properties", ignoreResourceNotFound=true)
#PropertySource(value= "classpath:migration-test.properties")
#Import({BpmConfig.class, MonitorConfig.class})
#ActiveProfiles({"monitor-elasticsearch"})
public class TestConfig {
...
}
The problem is when I push such a test and run build in CI (Teamcity) it still tries to scan everything defined in TestConfig.class even all tests are ignored. Can I override somehow this behaviour ?

Related

Cannot load #Configuration class in component test marked as #SpringBootTest

I am testing a functionality and has written a componentTest to ensure the component is working. The issue is when running the test #Configuration class is not loading for the test. Example:
TestClass:
#SpringBootTest(classes = Application.class)
public class ServiceTest{
//Do Something
}
#Configuration
public class ConfigurationClass{
#PostConstruct
public void doSomething(){
log.info("Test loading");
}
}
When running the application, I can see the logs printed on application startup. When I run the test, I don't see the logs printing from the ConfigurationClass. I tried using #ContextConfiguration(classes=ConfigurationClass.class) but no luck.
Practically , I want the configurationClass to be loaded before the tests are loaded.
When you run #SpringBootTest(classes = Application.class) with a specified class, its instructs the spring boot test engine to load only beans defined in Application.java which is supposed to (usually) be a class annotated with #Configuration annotation directly or indirectly.
If you want to just load the whole application context in the test, just use #SpringBootTest without any attributes. Now in this case it will scan packages up to one with #SpringBootConfiguration annotation (which presents on the class annotated with #SpringBootApplication and then will scan the packages down to load the configuration classes.
Of course you should make sure that the test will be able to find #SpringBootApplication class, for that you should put the test in the same package or beneath (of course the tests are in src/test/java as opposed to the src/main/java where you main class resides.

Replacing #SpringApplicationConfiguration by #SpringBootTest

I have a Spring Boot application with kinda lot unit tests. All the test classes are not annotated. They all just extend the following Abstract Class where they got their annotations from too:
#RunWith(SpringJUnit4ClassRunner.class)
#EnableAutoConfiguration
#SpringApplicationConfiguration(classes = { MoneyjinnConfiguration.class })
#WebAppConfiguration
#SqlGroup({ #Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = { "classpath:h2defaults.sql",
"classpath:testdata.sql" }) })
public abstract class AbstractTest {
}
Since Spring Boot 1.4.0 #SpringApplicationConfiguration is deprecated. I tried to replace it by #SpringBootTest and #ContextConfiguration(classes = { MoneyjinnConfiguration.class }) but now all my tests are failing with:
Caused by: java.lang.IllegalArgumentException: No auto-configuration attributes found. Is org.laladev.moneyjinn.businesslogic.service.impl.ContractpartnerAccountServiceTest annotated with EnableAutoConfiguration?
When I now annotate the concrete test-class with #EnableAutoConfiguration it continues to work again.
Honestly - I don't want to modify all my test classes by moving the #EnableAutoConfiguration from the abstract class to all concrete test classes. I kinda liked the approach of having all annotations in one central place - my AbstractTest class.
Am I missing something?

Disable Spring #EnableScheduling in Junit tests

I want to disable #Schedule in Spring tests but i can`t find a way to do it.
I have tried to make different config class for test environment but tasks are still fired.
This is config:
#Configuration
#EnableTransactionManagement
#EnableScheduling
#ComponentScan({"de.package"})
#PropertySource(name="application.properties", value="classpath:application.properties")
public class PersistenceJPAConfig {
...
}
This is test emvironment config.Just removed #EnableScheduling annotation
#Configuration
#EnableTransactionManagement
#ComponentScan({"de.package"})
#PropertySource(name="application.properties", value="classpath:application.properties")
public class PersistenceJPATestConfig {
...
}
In test i use:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { PersistenceJPATestConfig.class }, loader = AnnotationConfigContextLoader.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class GetArticlesTest {
...
}
But tasks are still fired when i run the test..Is there any way to stop executing tasks while running tests ?
As you're using #ComponentScan on the same package both time, it seems spring is loading the other configuration too.
You could use some profile to filter that, like adding this on your PersistenceJPATestConfig
#Profile("test")
add this annotation on your JUnit class so it will be executed with the "test" profile
#ActiveProfiles("test")
Edit :
Your main config should also be profiled so it is ignored when its profile is not active, so you should add another #Profile on the main config class with a different profile than "test"
Quick solution based on other answers(for spring boot users), just add below code to main configuration so that it wont run on test profiles and test cases! No other changes!
#Profile(!test)
public class Config{
......
}

Override application.properties for integration tests in spring-boot app

I have a standard spring-boot app and I want to use MS SQL database for the production environment, whereas for integration tests I'd like to use h2 databse. The problem is that I wasn't able to find out, how to override the default application.properties file. Even though I was trying to follow some tutorials, I didn't come up with the right solution...maybe I'm just missing something...
The main class:
#SpringBootApplication
#EnableTransactionManagement
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication .class, args);
}
}
and the class with tests:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = MyApplication.class)
#WebIntegrationTest
public class MessageControllerTest {
#Autowired
MessageRepository messageRepository;
...
...
...
#Test
public void testSomething(){
...
...
...
...
}
}
So the question is, how to force the spring-boot to use application-test.properties file when running the tests, instead of application.properties, which should be used during the run time.
I tried for example to replace #WebIntegrationTest annotation with #TestPropertySource(locations="classpath:application-test.properties"), but this results in java.lang.IllegalStateException: Failed to load ApplicationContext.
Assuming you have a application-test.properties file in your app.
I do it in two ways :
1.CLI JVM Args
mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=test
add the application-test.properties as an active profile.
add the spring.profiles.active=test in the application.properties and it will load your application-test.properties file.
As you pointed to in your answer annotate a class test with a specific active profile ( which is not suitable when having a large test classes i think ) #ActiveProfiles("test")
Actually it was pretty easy...after several hours of trying, I've realized that I just needed to annotate my test class with #ActiveProfiles("test") annotation.
#ActiveProfiles("test")
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = MyApplication.class)
#WebIntegrationTest
public class MessageControllerTest {
#Autowired
MessageRepository messageRepository;
...
...
...
#Test
public void testSomething(){
...
...
...
...
}
}

Junit Suites with Spring autowired elements

I have a collection of Junit test classes with an autowired element (Spring). If I execute each Junit test class separately, everything works ok.
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
public class TestClass {
#Autowired
MyController control;
#Test
public void geolocTest() throws Exception {
...
}
I want to create a "Test Suite", but if I execute the Test Suite, it looks like the autowired elements are "null", so every test fails.
#RunWith(Suite.class)
#Suite.SuiteClasses({
TestClass.class
})
public class TestSuit extends TestCase {
...
}
What can I do? Thanks
NOTE:
What I want is to execute a code before all test classes, and another code after all test classes. I think I need a Suite for this...
As mentioned, you should use:
#RunWith(SpringJUnit4ClassRunner.class)
You can use #Before, #After, #BeforeClass, #AfterClass.
First two will be executed before and after each test case in a given Test class.
Last two will be executed only once per given Test class.
Your tests should be atomic as much as possible, so if you have all Test cases mutually dependent on same data or order of execution, try to rewrite this first.
If you wish to share some application properties, the good thing, for auto wiring between all test cases, such as the urls to mocks, take a look at the Spring profiles.
You can then have production specific and test specific properties which will be injected based on the current profile.
Take a look at the example and official docs:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html
http://www.mkyong.com/spring/spring-profiles-example/
#Configuration
#ComponentScan
#Profile("test")
#PropertySource(value = "classpath:/yourApp.properties")
public class TestConfiguration {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
You can then injected shared properties from the file in your test classes like this:
#Value("${mock.url}")
private String mockUrl;
Your missing at least the following
#RunWith(SpringJUnit4ClassRunner.class)
on your TestClass.

Categories