Spring Data - MongoDB - JUnit test

16,643

Solution 1

For Spring Boot 1.5.8.RELEASE

You can use @SpringBootTest to bootstrap all you spring configurations.

Your test will look like

@RunWith(SpringRunner.class)
@SpringBootTest
public class SomeRepositoryTests {

    @Autowired
    private SomeRepository someRepository;

    @Test
    public void someTest() {
        someRepository.someMethod(...);
        // assertions
    }
}

Of course you want to use embedded mongodb for test so add

for Maven

<dependency>
  <groupId>de.flapdoodle.embed</groupId>
  <artifactId>de.flapdoodle.embed.mongo</artifactId>
  <scope>test</scope>
</dependency>

for Gradle

testCompile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')

Solution 2

Your repo CustomerRepository doesn't require @Configuration or @Repository annotations. Spring will do it for you as you extends base Repository classes.

To setup Mongo Repositories you need to extend ApplicationContext with the following annotations.

@Configuration
@EnableAutoConfiguration // create MongoTemplate and MongoOperations
@EnableMongoRepositories(basePackages = "hello.test") // Create your repos
public class ApplicationConfig {

}

You also would like to use in-memory database for you unit/integration tests so them won't alter productions database.

To enable it just add the following dependency:

<dependency>
  <groupId>de.flapdoodle.embed</groupId>
  <artifactId>de.flapdoodle.embed.mongo</artifactId>
  <version>1.50.2</version>
  <scope>runtime</scope>
</dependency>

Finally, configure you test class with the ApplicationContext

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ApplicationConfig.class)
public class MyJUnitTest {
    // Test cases ...
}    
Share:
16,643
quma
Author by

quma

I'm a software developer in Java (Spring), JavaScript, AngularJS, Angular, TypeScript.

Updated on June 19, 2022

Comments

  • quma
    quma almost 2 years

    I would have a question concerning Spring Data - MongoDB and JUnit test.

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = { UserRepository.class, User.class })
    public class MyJUnitTest {
    

    The UserRepository looks like this:

    @Repository
    public interface UserRepository extends MongoRepository<User, String> {
        User findByUsername(final String username);
    }
    

    I get the following Exception:

    Failed to instantiate [... .repository.UserRepository]: Specified class is an interface

    My question now would be, how to do it, that UserRepository is instantiate although there is no implementation class because Spring Data does the implementation by its own? If I do not mark USerRepository with @Repository than Spring does not create a bean object

    [EDIT]

    I have tried the example of the link you posted and it works fine if I run the application over the main- method. Then I tried to implement a test class but in this case I get the same exception:

    Error creating bean with name 'hello.test.TestClass': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private hello.CustomerRepository hello.test.TestClass.repository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [hello.CustomerRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    My test class looks like this in src/test/java/hello/test (hello.test is the package):

    @ComponentScan("hello")
    @EnableMongoRepositories(basePackages = "hello")
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = { CustomerRepository.class,     Customer.class })
    public class TestClass {
    
    @Autowired
    private CustomerRepository repository;
    
    @Test
    public void testMethod() {
        System.out.println("repositoryd: " + repository);
        }
    }
    

    and my CustomerRepository looks like this (with @Configuration annotation):

    @Configuration
    public interface CustomerRepository extends MongoRepository<Customer, String> {
    
    public Customer findByFirstName(String firstName);
    
    public List<Customer> findByLastName(String lastName);
    
    }
    

    Actually I don't know which annotations I need in order to get the test running - Maybe you would have another suggestion in order that I can solve this issue.