spring boot - spring data jpa error - spring

main class annotations -
#SpringBootApplication
#ComponentScan( basePackages = "com.webstar" )
#EntityScan(basePackages = "com.webstar.models" )
#EnableJpaRepositories(basePackages = "com.webstar.repository")
#EnableAutoConfiguration
public interface UserAccounts extends JpaRepository<Registration, Long>
{
}
my test class -
#RunWith( SpringJUnit4ClassRunner.class )
#WebAppConfiguration
public class RegistrationTest
{
#Autowired
private UserAccounts userRepo;
#Test
public void testRegistration()
{
Registration reg = new Registration("1212","1212","1212","121","1212",null,null);
userRepo.save(reg);
}
}
Error - Caused by the following:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
My repository and models are in different packages.

Let's say that you have the following configuration:
Your entity package com.other.model
Your repository package: com.other.repository
Your testing class that is in a totally different package: foo.test.mydemo.MyOtherAppTest
Go to foo.test.mydemo.MyOtherAppTest class and add the following annotation:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
#SpringBootConfiguration
#EnableAutoConfiguration
#EntityScan(basePackages = "com.other.model")
#EnableJpaRepositories(basePackages = "com.other.repository")
public class MyOtherAppTest {

on you RegistrationTest.class
add annotation:
#SpringApplicationConfiguration(class=classname.class)
//classname is you main class name
if you use springBootTest
use #SpringBootTest(class=classname.class)
//classname is you main class name
wish help you ~

Related

No qualifying bean of type repository when running test but not main application

I'm developing a Spring Boot application following TDD methodology. I've created the main classes (controller, service and repository) this way:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class CrimeServiceImpl implements CrimeService{
#Autowired
private CrimeRepository repository;
...
Controller:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class CrimeController {
#Autowired
private CrimeServiceImpl service = new CrimeServiceImpl();
Repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CrimeRepository extends JpaRepository<Crime, Long>{
}
This is the project structure:
If I run the application normally, no error. The classes' methods are empty. Then I've created a test class like this:
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = CrimeServiceImpl.class)
#ComponentScan("com.springmiddleware")
#AutoConfigureMockMvc
#SpringBootTest
public class TestCrimeService {
//Calling method getAllCrimes works
#Test
public void returnAllCrimesExists() throws NoSuchMethodException, SecurityException {
List<Crime> list = new ArrayList<>();
assertTrue(this.service.getAllCrimes() == list);
}
And if I run this, the following error is shown and the test fails:
NoSuchBeanDefinitionException: No qualifying bean of type 'com.springmiddleware.repository.CrimeRepository' available: expected at least 1 bean which qualifies as autowire candidate.
I've checked all annotations and it seems to me that all is ok, and I thought if I missed something, even in the normal run the application would fail. What did I got wrong?
I wanted also to make a test class for a JPARepository, and I also encountered the same error message:
NoSuchBeanDefinitionException: No qualifying bean of type
'SomethingRepository' available:
expected at least 1 bean which qualifies as autowire candidate.
I could make it work by adding the 2 following annotations on top of the test class:
#EnableJpaRepositories(basePackageClasses = SomethingRepository.class) // repository
#EntityScan(basePackageClasses = Something.class) // entity of the repository
Now it looks like:
#RunWith(SpringRunner.class)
#EnableJpaRepositories(basePackageClasses = SomethingRepository.class) // repository
#EntityScan(basePackageClasses = Something.class) // entity of the repository
#SpringBootTest(classes = MyDbUnitTestApp.class) // does some #ComponentScan and #EntityScan on the repositories/entities package, and #EnableAutoConfiguration
#ActiveProfiles(Profiles.myTestProfile)
#DatabaseSetup(value = {
"/datasets/dataset1.xml" }, type = DatabaseOperation.CLEAN_INSERT)
public class SomethingRepositoryTest {
#Autowired
private SomethingRepository sut;
#Test
public void findById() {
Something something= sut.findById(1L);
Assert.assertEquals("foobar", something.getName());
}
}

#EnableAutoConfiguration on AbstractIntegrationTest possible?

Having lots of Integration-Test Implementations like this:
// no #Annotations at all
class SomeIntegrationTest extends AbstractIntegrationTest {
...
}
using (Spring Boot 1.5, JUnit 5)
#SpringBootTest(classes = {CoreConfiguration.class, RestTemplateAutoConfiguration.class, JacksonAutoConfiguration.class})
#ExtendWith(SpringExtension.class)
#AutoConfigureMockMvc
#Transactional
public abstract class AbstractIntegrationTest {
...
}
this is always failing with
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
unless I annotate every IntegrationTest-Implementation with
#EnableAutoConfiguration
class SomeIntegrationTest extends AbstractIntegrationTest {
...
}
I wonder why I cannot #EnableAutoConfiguration the AbstractIntegrationTest and be done with it.
(When doing so, it fails with IllegalArgumentException: No auto-configuration attributes found. Is package.SomeIntegrationTest annotated with EnableAutoConfiguration?)
Our normal Apps look like this:
#SpringBootApplication
#Import({CoreConfiguration.class, OtherConfiguration.class})
public class WebApp {
here the #SpringBootApplication obviously implies #EnableAutoConfiguration but I would like to avoid annotating each and every *IntegrationTest with this and instead configure it once on the AbstractIntegrationTest.
Is this fighting against spring-boot in any way or is there some way to achieve this? Thanks.
You could create update your AbstractIntegrationTest abstract class to have a small inner configuration class e.g. TestConfiguration which is loaded using the #Import(TestConfiguration.class) annotation.
#SpringBootTest(classes = {CoreConfiguration.class, RestTemplateAutoConfiguration.class, JacksonAutoConfiguration.class})
#ExtendWith(SpringExtension.class)
#AutoConfigureMockMvc
#Transactional
#Import(AbstractIntegrationTest.TestConfiguration.class) // <---- import the configuration
public abstract class AbstractIntegrationTest {
#EnableAutoConfiguration
// Any other applicable annotations e.g. #EntityScan
static class TestConfiguration {
}
....
}

Spring Actuator - How to exclude HealthEndpoint from autowiring in test

I am trying to run a test but I got an exception when I try to run it Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.actuate.endpoint.HealthEndpoint' available:
I have two packages com.test.data and com.test.health in my main folder. My main Application class is in com.test.data. In com.test.health I have one class with name StartupHousekeeper implements ApplicationListener<ApplicationReadyEvent> and autowired HealthEndpoint there as below
#Component
public class StartupHousekeeper implements ApplicationListener<ApplicationReadyEvent> {
#Autowired
private HealthEndpoint healthEndpoint;
}
In test I have ControllerIntegrationTest which is config class and code is below. Even though I did not add com.test.health package it is still throwing NoSuchBeanDefinitionException.
#Profile("controller-integration-test")
#ComponentScan(basePackages = {"com.test.data"})
#Configuration
public class ControllerIntegrationTest {
}
My actual test class is below
#TestExecutionListeners(MockitoTestExecutionListener.class)
#ActiveProfiles({"controller-integration-test"})
#ContextConfiguration(classes = ControllerIntegrationTest.class)
#WebMvcTest(value = AdminUserController.class, secure = false, excludeAutoConfiguration = {HealthIndicatorAutoConfiguration.class, HibernateJpaAutoConfiguration.class, FlywayAutoConfiguration.class, DataSourceAutoConfiguration.class})
public class AdminUserControllerTest extends AbstractTestNGSpringContextTests implements TestConstants {}
When I try to run it org.springframework.test.context.testng.AbstractTestNGSpringContextTests#springTestContextPrepareTestInstance failed to run due to above mentioned exception

#ComponentScan takes no effect

I have the following code:
Implementation of Bean:
package my.persist.services;
#Component
public class MyService{
}
Test:
package my.persist.services;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={"other configuration classes", my.persist.services.MyService.class})
#ComponentScan(basePackageClasses = {my.persist.services.DummyPlaceHolder.class})
public class MyServiceTest extends AbstractJUnit4SpringContextTests {
#Autowired
MyService service;
}
When I remove "my.persist.services.MyService.class" from #ContextConfiguration, the compiler says "Could not autowire, no bean of ... found", it seems the #ComponentScan has no effect? Any help?
Rather than component scan for individual classes, does a wildcard scan of your base package work?
#ComponentScan(basePackages = {"my.persist.services.*"})
You can exclude certain ones in your test, i.e if you want to filter out your real implementation in your test, you can do the following:
#ComponentScan(basePackages = {"my.persist.services.*"}, excludeFilters={
#ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=MyService.class)})

Spring JPA Repository instance not created

I followed the example that the Spring organization provides here for Spring Data JPA.
This is my repository interface:
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
And this is a snippet of my Application class:
#Configuration
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class);
CustomerRepository repository = context.getBean(CustomerRepository.class);
I get the following error :
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [hello.CustomerRepository] is defined
I tried adding a #Repository annotation to CustimerRespository and the #ComponentScan annotation to the Application class, but result is the same.
I had the same problem and #EnableAutoConfiguration solved it.
If it doesn't work automatically, try disabling JpaRepositoriesAutoConfiguration and explicitly specify the repositories base package:
#EnableAutoConfiguration(exclude = {
JpaRepositoriesAutoConfiguration.class
}
#EnableJpaRepositories(basePackages = {"com.project.app.repositories"})
Good luck.
Maybe try adding on your configuration class
#EnableJpaRepositories
#EnableConfigurationProperties()
#EntityScan({"com.project.app.entities" })
try to add #EnableJpaRepositories and #ComponentScan annotations in Application class to see if adding them solve your problem.
If still it doesn't work, add #Configuration in your CustomerRepository interface and then in Application class add #Import(CustomerRepository .class).
let me know if works.

Resources