Testing the Data Access Layer in Spring-Boot

I easily wrote the data access layer in spring-boot, but took some time till I figured out that the @ComponentScan annotation is required to test it.

I wanted to test this Repository:

@Repository
public class UserRepository {
    public User findByEmail(String email) {
        return entityManager.find(User.class, email);
    }

    @PersistenceContext
    private EntityManager entityManager;
}

The test case was also simple (based on the samples and documentation):

@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private UserRepository repository;

    @Test
    public void findsUserByEmail() {
        User user = new User("email", "password");
        entityManager.persist(user);
        assertEquals(user, repository.findByEmail("email"));
        assertNull(repository.findByEmail("email2"));
    }
}

Unfortunately, it didn’t work as promised. I was keep getting this error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.zsoltfabok.authservice.domain.UserRepositoryTest':Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.zsoltfabok.authservice.domain.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
  at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)

The missing item is the @ComponentScan annotation on the TestCase:

@RunWith(SpringRunner.class)
@DataJpaTest
@ComponentScan("com.zsoltfabok.authservice.domain")
public class UserRepositoryTest {
   // ...
}

I don’t know why it isn’t part of the official documentation.


comments powered by Disqus