Spring Consul - disable for unit tests - spring

Updated
My class listed below (ServiceDiscoveryConfiguration) is never being utilized. Even if I remove the #EnableDiscoveryClient to attempt to completely avoid the setup, it still attempts to connect to Consul.
The only thing that worked for me was removing the Consul Maven depdency completely:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
What can I do to prevent Consul for running for unit tests if not through the profile and annotation setup?
Original
I have an application using Spring Consul.
I have a class set up to enable discovery like this:
#Profile ("!" + Profiles.UNIT_TEST)
#Configuration
#EnableDiscoveryClient
public class ServiceDiscoveryConfiguration {
}
This should be disabling the Consul portion, if I am not mistaken. The base test class (it's an abstract shared between all of my unit tests) is setup up with the following annotations. This is where I think the problem is.
#SpringBootTest (classes = Service.class)
#WebAppConfiguration
#TestExecutionListeners (...)
#DirtiesContext
#ActiveProfiles (Profiles.UNIT_TEST)
#Test (...)
public abstract class AbstractBootTest extends AbstractTestNGSpringContextTests {
// ...
}
When I execute my tests I get:
Caused by: com.ecwid.consul.transport.TransportException:
java.net.ConnectException: Connection refused
This leads me to believe that the profile activation is not working or my syntax using the ! operator on the #Profile specification is not doing what I thought it was supposed to be doing. The root execution class itself has basic annotations including a #ComponentScan annotation that I know has the appropriate packages being scanned.
Assistance?

You can disable via
#TestPropertySource(properties = {"spring.cloud.consul.config.enabled=false"})

if you have bootstrap.properties file in your project, you should create bootstrap.properties file under test/resources:
spring.application.name=<service-name>
spring.cloud.bus.enabled=false
spring.cloud.discovery.enabled=false
spring.cloud.consul.enabled=false
spring.cloud.consul.config.enabled=false
This will disable consul integration in tests

Add below property in your application.properties file under test/resources
spring.cloud.discovery.enabled=false
spring.cloud.consul.enabled=false
spring.cloud.consul.config.enabled=false
This will disable consul integration while testing your application

The problem is that if you have spring-consul in the classpath it will try to auto-configure it anyway

The profile annotation is correct
#Profile ("!" + Profiles.UNIT_TEST)
the profile activation looks ok, also
#ActiveProfiles (Profiles.UNIT_TEST)
You wrote you are using ComponentScan, that is important, because #Profile annotation on a bean is ignored, if the bean is instantiated by a #Bean annotated method. May be you check again, to see, this does not happen ?
To narrow down the problem you can try :
set a breakpoint in the constructor of ServiceDiscoveryConfiguration, to see if it is instantiated or not
remove #EnableDiscoveryClient to see if this is really the cause of your problems

Related

Springboot build not working because of test configuration

I have started a spring boot project using start.spring.io.
But I am getting this error-
I have read various articles on the internet about this issue and they all say about putting my tests in the same package as my Main class.
But I already have the same.
Could you point out what is wrong with my configuration?
The exception is pretty clear: You are missing a configuration for your spring context. What you need to do is to add the configuration classes for your context like so:
#SpringBootTest(classes = { TestConfiguration.class })
whereas your TestConfiguration class must be annotated with
#Configuration
and/or
#EnableAutoConfiguration
There you can add configurations to your liking. You can of course also use your DatabaseApplication class as Configuration although Im wouldn't recommend that.
The search algorithm works up from the package that contains the test until it finds a #SpringBootApplication or #SpringBootConfiguration annotated class. As long as you’ve structure your code in a sensible way your main configuration is usually found.
Make Sure your DatabaseApplication class is annotated with #SpringBootApplication .

Disable autoconfiguration for Spring Cloud Config in a test class of a Spring Boot application

I have a test class annotated with #DataJpaTest which autoconfigures Cloud Config.
I want to stop that for that one test class. I cannot use the spring.cloud.config.enabled=false application property, because that would disable it for all tests.
Any suggestions?
#DataJpaTest annotation has other attributes. I tried the following to specifically disable the Spring Cloud Config and it worked for me locally:
#DataJpaTest(properties = {"spring.cloud.config.enabled=false"})
#DataJpaTest takes a excludeAutoConfiguration argument. You can specify all the AutoConfig's which you want to exclude.
#DataJpaTest(excludeAutoConfiguration = {AbcCloudAutoConfig.class, DefCloudAutoConfig.class})
replace AbcCloudAutoConfig, DefCloudAutoConfig with the classes you want to exclude

Spring Boot 1.5 #JdbcTest failing when using Eureka Discovery

I'm trying to use the new #JdbcTest annotation in Spring boot 1.5.0.RC1.
My app uses Eureka discovery ie I have
compile('org.springframework.cloud:spring-cloud-starter-eureka')
in my build.gradle and
#EnableDiscoveryClient
on my main Spring Boot class
When I try to use #JdbcTest to test a JdbcTemplate based DAO I get this error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method eurekaHealthIndicator in org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration$EurekaHealthIndicatorConfiguration required a bean of type 'com.netflix.discovery.EurekaClient' that could not be found.
Action:
Consider defining a bean of type 'com.netflix.discovery.EurekaClient' in your configuration.
It looks like the auto configuration is loading part of the Eureka configuration when it should only load JDBC related beans.
If I add
#TestPropertySource(properties={"eureka.client.enabled=false"})
to the test the problem goes away, but I think #JdbcTest should be making sure already that only relevant beans are loaded.
Am I missing something or is this a problem with the new #JdbcTest, or maybe Spring Cloud Eureka?
Your #SpringBootApplication has # EnableDiscoveryClient on it. When you use a slice annotation (such as #JdbcTest), Spring Boot finds the context to use by looking at the package of your test for a #SpringBootConfiguration. If it does not find one, it looks in the parent package, etc. With a sensible package structure and no further customization, your tests use your #SpringBootApplication as the root context.
So, that configuration class (and only that one) is processed an #EnableDiscoveryClient is also obviously processed. In your case, this has an additional side effect: every single test now requires the Eureka Client.
TL;DR never put such annotation on your application. And only put it if you actually need it. You could define a #Configuration class next to your Spring Boot app for those.
#David
I had similar issue and fixed by adding the following to my application.yml file
eureka:
client:
enabled: false

Spring-Boot module based integration testing

I have a multi-module Spring-Boot project.
I was wondering how I can set up integration testing just to test Spring Data JPA repositories? The following approach fails with this exception:
HV000183: Unable to load 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath.
Since this module does not depend on the web module, there is no web application that can be started.
#RunWith(SpringJUnit4ClassRunner.class)
#IntegrationTest
#SpringApplicationConfiguration(classes = TestConfiguration.class)
class CardInfoRepositoryIT {
#Autowired CardInfoRepository cardInfoRepository;
#Test
void testLoadData() {
assert cardInfoRepository.findAll().size() == 1
}
}
As Marten mentioned, #IntegrationTest should only be used when you need to test against the deployed Spring Boot application (e.g., deployed in an embedded Tomcat, Jetty, or Undertow container). So if your goal is to test your repository layer in isolation, you should not use #IntegrationTest.
On the other hand, if your tests require specific Spring Boot functionality (in contrast to standard Spring Framework functionality, semantics, and defaults), then you will in fact want to annotate your test class with #SpringApplicationConfiguration instead of #ContextConfiguration. The reason is that #SpringApplicationConfiguration preconfigures the SpringApplicationContextLoader which is specific to Spring Boot.
Furthermore, if you want your repository layer integration tests to run faster (i.e., without the full overhead of Spring Boot), you may choose to exclude configuration classes annotated with #EnableAutoConfiguration since that will auto-configure every candidate for auto-configuration found in the classpath. So, for example, if you just want to have Spring Boot auto-configure an embedded database and Spring Data JPA (with Hibernate as the JPA provider) along with entity scanning, you could compose your test configuration something like this:
#Configuration
#EnableJpaRepositories(basePackageClasses = UserRepository.class)
#EntityScan(basePackageClasses = User.class)
#Import({ DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
public class TestRepositoryConfig {}
And then use that configuration in your test class like this:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = TestRepositoryConfig.class)
#Transactional
public class UserRepositoryTests { /* ... */ }
Regards,
Sam
p.s. You might find my answer to the following, related question useful as well: Disable security for unit tests with spring boot
I resolved this by having the following test config class.
#Configuration
#EnableAutoConfiguration
#ComponentScan
#PropertySource("classpath:core.properties")
class TestConfiguration {
}
core.properties is also used by the main application and it contains datasource information. #IntegrationTest annotation can be removed on the test class.
I also added the following to the module as dependencies:
testRuntime 'javax.el:javax.el-api:2.2.4'
testRuntime 'org.glassfish.web:javax.el:2.2.4'

SpatialRepository not autowiring

Does anyone know how to get SpatialRepository #Autowiring in a spring boot app? I have put the additional dependency in my classpath
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-spatial</artifactId>
<version>0.9</version>
</dependency>
with the following configuration options
#SuppressWarnings("unused")
#Configuration
#EnableAutoConfiguration
#EnableTransactionManagement
#EnableNeo4jRepositories(basePackages = {"com.eanda.prototype", "test.com.eanda.prototype"})
#ComponentScan({"com.erranda.prototype", "org.springframework.data.neo4j"})
I have tried it all but no avail. My domain class is this:
public interface ErrandRepository extends GraphRepository<Errand>, SpatialRepository<Errand> {}
I get the following exception when running a query on the spatial repo
java.lang.IllegalArgumentException: No index provider 'spatial' found. Maybe the intended provider (or one more of its dependencies) aren't on the classpath or it failed to load.
Are you introducing the spatial engine to an existing database?
Have you installed the spatial extension in the plugin directory?
Lorenzo

Resources