Mockito or Embedded Mongo for unit testing spring mongorepository

Viewed 34

Hi I am new to Spring Mongo testing. I know that using embedded db like flapdoodle ,fongo,mongo-java-server we can unit test the mongorepository. But is the same possible using mockito? If yes then which is better

1 Answers

Mockito is used for mocking calls to external dependencies. Utilities like flapdoodle are used to mock external dependencies (MongoDB in this case). It's just two different approaches.

  1. You can mock methods of your repository classes to return some stub values instead of making calls to the database. Please see my example below for this case:
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import static org.mockito.Mockito.doReturn;

class FooRepositoryTest {

    @Mock
    private FooRepository repository;
    
    @Test
    void testGetById() {
        doReturn(new Object()).when(repository).findById("id");
        Object object = repository.getById("id");
    }
}
  1. You can mock your database (by just instantiating some other test-embedded database) and make actual calls to it in your tests. This is where flapdoodle comes in handy. In this case, you will be using your actual repositories/services/etc. Please see my example below:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@DataMongoTest
@ExtendWith(SpringExtension.class)
class FooMongoRepositoryTest {
    
    @Autowired
    private FooRepository repository;
    
    @Test
    void testGetById() {
        Object object = repository.getById("id");
    }
}

But the second case won't be a true unit test, since it will be using an external dependency. At the same time, it won't be a true integration test, since your real application uses a real Mongo database and not some flapdoodle dependency.

Answering your question regarding what is better. It depends on the particular case. It's fully acceptable to use either of these options. It even makes sense to use both because it's just two different types of developer tests.

What else you may consider:

There is a nice library called testcontainers, which allows you to run real databases and other services in Docker containers. It even has a separate and preconfigured MongoDB Module

Related