2
  1. I'm using Spring Boot and MongoDB to create a simple school application. I want to test the methods that are defined in the service class but I get the following exception:

    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name'com.backintime.BackInTimeSpring.Service.TeacherServiceTest': Unsatisfied dependency expressed through field 'teacherService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying     bean of type 'com.backintime.BackInTimeSpring.Service.TeacherService' available:     expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:    {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    
  2. My classes are the following:

  3. Repository:

    package com.backintime.BackInTimeSpring.Model.Repository;
    @Component
    @Repository
    public interface ITeacherRepository extends MongoRepository<Teacher,String> {
    
    @Query("{}")
    Stream<Teacher> findAllTeachers();
    
    List<Teacher> findByLastNameIgnoreCase(String lastName);
    List<Teacher> findByFirstNameIgnoreCase(String firstName);
    
    }
    
  4. Service:

    package com.backintime.BackInTimeSpring.Service;
    @Component
    @Service
    public class TeacherService {
    @Autowired
    private ITeacherRepository teacherRepository;
    
    public List<Teacher> retrieveAllTeachers(){
        return       this.teacherRepository.findAllTeachers().sorted(Comparator.comparing(Teacher::getLastName)).collect(Collectors.toList());
    }
    public Teacher retrieveTeachersById(String id) {
        return this.teacherRepository.findAllTeachers().filter(t -> t.getId().equals(id)).findFirst().get();
    }
    public List<Teacher> retrieveTeachersByLastName(String lastName){
        return this.teacherRepository.findByLastNameIgnoreCase(lastName);
    }
    public List<Teacher> retrieveTeachersByFirstName(String firstName){
        return this.teacherRepository.findByFirstNameIgnoreCase(firstName);
    }
    public void saveTeacher(Teacher t){
        this.teacherRepository.save(t);
    }
    
    public String greet() {
        return "Hello World";
    }
    

    }

  5. Unittest:

    package com.backintime.BackInTimeSpring.Service;
    @RunWith(SpringRunner.class)
    @ComponentScan(basePackages = "com.backintime.BackInTimeSpring")
    public class TeacherServiceTest {
    
    @Autowired
    TeacherService teacherService;
    @Test
    public void retrieveAllTeachers() {
        assertEquals(3, teacherService.retrieveAllTeachers().size());
    }
    
Cœur
  • 37,241
  • 25
  • 195
  • 267
Wat Als
  • 33
  • 4
  • Can you try to annotate the bean with @Component and let us know if it worked? – OEH Dec 11 '18 at 11:00
  • Still the same error :( – Wat Als Dec 11 '18 at 11:39
  • 1
    Drop `@ComponentScan`. Replace with `@SpringBootTest`. Note the parameters to `@SpringBootTest` if you need to customize. Normally one would use the `classes` parameter to point it at your annotated main application class (the one with `@SpringBootApplication` on it). Also drop `@Component` on classes where you also have `@Service` because `@Service` imports `@Component`. – Andy Brown Dec 11 '18 at 15:23
  • Andy .. THANK YOU, that solved it for me. I'll edit the code – Wat Als Dec 12 '18 at 09:09

1 Answers1

1

This is happening due to the fact that you are using @ComponentScan in the wrong place.

Usually it is used in your Main Application class or in configuration classes not where you define the beans.

Please refer to this link: https://springframework.guru/spring-component-scan/

There is a similar question in here, and as you can see they are as well using @ComponentScan in the Main application

How to use @ComponentScan together with test-specific ContextConfigurations in SpringJunit4TestRunner?

OEH
  • 665
  • 11
  • 29