#TestPropertySource breaks context and other tests fail - java

In that class I add the #TestPropertySource:
#TestConfig
#TestInstance(PER_CLASS)
#TestPropertySource(properties = {"name=BigSam"})
class Test5 {
//...tests
}
I have 5 integration tests. The common configuration for tests:
#Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#SpringBootTest(classes = MainStart.class)
#ActiveProfiles("test")
public #interface TestConfig {}
If I run the Test5 separately it works fine. But, when I run all integration tests together including Test5 class, I see in the logs:
" The following 1 profile is active "test" " - more than one time. ( If I run an integration test without Test5 class, this message appears only one time)
And I the errors:
java.lang.IllegalStateException: Failed to load ApplicationContext
javax.cache.CacheException: A Cache named "cache-name" already exists.
How can the configuration of the test be fixed?
Or how can I change the property source and don't get such errors?
p.s. I use cache from Hibernate, but I don't think that it is a problem.

Related

Trouble executing a unit test that should ignore Spring annotations on the unit under test

I'm trying to execute a unit test for a service class that has an #Async("asyncExecutor") annotated method. This is a plain JUnit test class with no Spring runners and no intention of using Spring at all in the unit test. I get the exception,
BeanFactory must be set on AnnotationAsyncExecutionAspect to access qualified executor 'asyncExecutor'
Where asyncExectuor is the name of the bean to be used during normal execution. My configuration class looks like this and I solved that previous error message at runtime by adding the mode = AdviceMode.ASPECTJ portion. This service works at runtime without issue in an Async way.
#Configuration
#EnableAsync(mode = AdviceMode.ASPECTJ)
public class AsyncConfiguration {
#Bean(name = "asyncExecutor")
public Executor asyncExecutor() {
...
}
}
I don't understand why the Spring context is being constructed at all in the unit test. The test class is simply annotated #Test on the methods with no class annotations and no mention of Spring. I was hoping to unit test this service class method as a regular method ignoring the async nature, but the annotation is being processed for some reason.
I'm contributing to a much larger gradle + Spring 4 project that I'm not fully knowledgeable about. Is there anything I should be looking for to see if a Spring context is being created by default for all tests?
As you noticed, Spring context is not loaded, that is the reason of your error. Try to initialize Spring context in your test by adding #RunWith and #ContextConfiguration annotations

#SpringBootTest annotation giving Failed to load ApplicationContext Error

New to spring. I am trying to upgrade spring-boot-starter-parent from v1.3.2 to the latest v2.1.4. Made the POM file change for version upgrade. I have made all the necessary code changes to solve the compilation problems. when I am trying to run the test cases though, Test Classes which have #SpringBootTest annotation are failing with java.lang.IllegalStateException: Failed to load ApplicationContext
I have my application properties(application.properties) file in src/main/resources and the test application.properties file in src/text/resources
I have tried various annotations like
#ContextConfiguration()
#TestPropertySource(locations = "classpath:application.properties")
Still received the same error.
Below is the sample test class created.
package xxx.xx.xx.xxxx.controller
import org.junit.Assert;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = App.class)
#WebAppConfiguration
public class SampleTest {
//sample test case created to figure out
//test case runs successful when #SpringBootTest is not present
#Test
public void sampleTest1() {
int x= 2+3;
Assert.assertEquals(5, x);
}
}
I expect to able to run the test cases with that annotation.

Spring boot cucumber TestExecutionListener before database initalization

I want to create integration test with docker before cucumber test start. Inspired by: http://tech.asimio.net/2016/08/04/Integration-Testing-using-Spring-Boot-Postgres-and-Docker.html
But in my case the TestExecutionListener is not started before database initialization. I use Flyway for database migrations and it seems it tries to initialize first. For this a database connection required, which is not available, due the TestExecutionListener not being executed.
These are my classes:
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {"json:target/integration-cucumber.json"},
features = "src/test/resources"
)
public class CucumberIntegration {
}
And my test class which I will be extended by the cucumber steps:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = Application.class)
#SpringBootConfiguration
#ContextConfiguration
#TestPropertySource(locations="classpath:application.properties")
#TestExecutionListeners({
DockerizedTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class
})
public class SpringIntegrationTest {
}
When I change #SpringBootTest(classes = Application.class) to #SpringBootTest I see DockerizedTestExecutionListener being executed. Only it fails because it misses configuration from Application.class.
Anyone idea how to this with or without TestExecutionListener?
This will not work because the Cucumber.class JUnit runner doesn't support TestExecutionListeners.
You might think that your test steps are executed by the SpringRunner.class JUnit runner, but they aren't.
The #RunWith(SpringRunner.class) annotation on your SpringIntegrationTest class is basically useless here, since according to your post, your subclasses of SpringIntegrationTest contain Cucumber steps. However the SpringRunner expects JUnit #Test methods. Cucumber steps with #Given, #When, #Then etc. are ignored because SpringRunner doesn't know what to do with them.
What really executes your test steps is the #RunWith(Cucumber.class) annotation in your CucumberIntegration class. The Cucumber runner, however, doesn't give a damn about the TestExecutionListeners annotation that your steps definition class inherits from SpringIntegrationTest because it doesn't support such a feature.
Execution listeners are a Spring-only feature. You won't be able to do what you want to do, at least not as long as you use Cucumber.

Spring Boot integration tests doesn't read properties files

I would like to create integration test in which Spring Boot will read a value from .properties file using #Value annotation.
But every time I'm running test my assertion fails because Spring is unable to read the value:
org.junit.ComparisonFailure:
Expected :works!
Actual :${test}
My test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {WebTests.ConfigurationClass.class, WebTests.ClassToTest.class})
public class WebTests {
#Configuration
#ActiveProfiles("test")
static class ConfigurationClass {}
#Component
static class ClassToTest{
#Value("${test}")
private String test;
}
#Autowired
private ClassToTest config;
#Test
public void testTransferService() {
Assert.assertEquals(config.test, "works!");
}
}
application-test.properties under src/main/resource package contains:
test=works!
What can be the reason of that behavior and how can I fix it?
Any help highly appreciated.
You should load the application-test.properties using #PropertySource or #TestPropertySource
#RunWith(SpringJUnit4ClassRunner.class)
#TestPropertySource(locations="classpath:application-test.properties")
#ContextConfiguration(classes = {WebTests.ConfigurationClass.class, WebTests.ClassToTest.class})
public class WebTests {
}
for more info: Look into this Override default Spring-Boot application.properties settings in Junit Test
Besides the above marked correct answer, there is another nature way to load application-test.properties: Set your test run "profile" to "test".
Mark your test cases with:
#ActiveProfiles("test")
#RunWith(SpringJUnit4ClassRunner.class)
application-xxxx.properties is a naming convention for properties of different "profile".
This file application-xxxx.properties should be placed in src/main/resources folder.
"Profile" is also useful in bean configuration.

JUnit Test Cases for Config

I have a javaconfig file that looks like this:
#Configuration
public class ServiceConfig {
#Autowired
FooBean someBean;
#Bean
#Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public FooService fooService() {
return new FooServiceImpl(someBean, fooB());
}
private Foo fooB() {
return new FooB();
}
}
And I have created a junit test file like so based on this stack answer :
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ServiceConfig.class)
public class ServiceConfigTest {
}
But I have a couple questions:
Should I test all my config files with this one junit test file? I have 4 config files in total including the ServiceConfig file, so in the ContextConfiguration should I just list them all out or have a junit test for each one indivually?
What am I supposed to test here? I tried reading this spring guide but I'm not really understand what behavior I should test here....just if something gets autowired successfully?
Should I test all my config files with this one junit test file? I
have 4 config files in total including the ServiceConfig file, so in
the ContextConfiguration should I just list them all out or have a
junit test for each one indivually?
In your test class, #ContextConfiguration must be positioned on the root of the class.
So for testing each configuration, you have to create a test class by Configuration.
What am I supposed to test here? I tried reading this spring guide but
I'm not really understand what behavior I should test here....just if
something gets autowired successfully?
Testing if autowired is successful seems not very useful. It would be as unit test that Spring feature works. If you want to unit test these classes, you should test your own processing. For the moment, you have not really. So, I am not sure that testing them has great value.
Test the intended behaviour of your system or individual units of functionally. As part of this the configs will be tested.
You don't need to make tests to make sure something is wired correctly. That should be implied on the basis that the functionality you are testing works.
You can aggregate multiple configurations into one configuration class using #Import.

Categories

Resources