1

I am using spring boot 1.5.x for application. Database is MONGO

Using MongoRepository for crud operations.

Earlier in our project we got dedicated test database instance so we have added mongodb properties of test db in src\test\resources\application.properties.

Now we dont have test db so we want to use embedded/fake db to test our classes Controller/Services/Repository etc..

Options are - embeded mongodb like flapdoodle and fongo

I tried 1 of solution de.flapdoodle.embed.mongo from SO question to use flapdoodle

de.flapdoodle.embed.mongo trying to download zip outside network : unable-to-download-embedded-mongodb-behind-proxy-using-automatic-configuration

I tried fakemongo but its not working for unit and integration testing of controller. Its picking mongo database details of test db using application.properties present in test/resources

pom.xml

        <dependency>
            <groupId>com.github.fakemongo</groupId>
            <artifactId>fongo</artifactId>
            <version>${fongo.version}</version>
            <!--<scope>test</scope> -->// not working, if removed it says cannot find mongo
        </dependency>

        <dependency>
            <groupId>com.lordofthejars</groupId>
            <artifactId>nosqlunit-mongodb</artifactId>
            <version>0.7.6</version>
            <scope>test</scope>
        </dependency>

FakeMongo Configuration

package com.myapp.config;

import com.github.fakemongo.Fongo;
import com.mongodb.MongoClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;


@Configuration
@EnableMongoRepositories
public class FakeMongo extends AbstractMongoConfiguration {

    @Override
    protected String getDatabaseName() {
        return "mockDB";
    }

    @Bean
    public MongoClient mongo() {
        Fongo fongo = new Fongo("mockDB");
        return fongo.getMongo();
    }

}

TestFakeMongo It works. Test executed properly - Reference http://springboot.gluecoders.com/testing-mongodb-springdata.html

package com.myapp.config;

import com.myapp.domain.entitlement.User;
import com.myapp.repository.UserRepository;
import com.lordofthejars.nosqlunit.annotation.UsingDataSet;
import com.lordofthejars.nosqlunit.core.LoadStrategyEnum;
import com.lordofthejars.nosqlunit.mongodb.MongoDbRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static com.lordofthejars.nosqlunit.mongodb.MongoDbRule.MongoDbRuleBuilder.newMongoDbRule;
import static org.junit.Assert.assertTrue;

@RunWith(SpringRunner.class)
@Import(value = {FakeMongo.class})
public class TestFakeMongo {

    @Autowired
    private ApplicationContext applicationContext;

    @Rule
    public MongoDbRule embeddedMongoDbRule = newMongoDbRule().defaultSpringMongoDb("mockDB");

    @MockBean
    private UserRepository userRepository;

    @Test
    @UsingDataSet(loadStrategy = LoadStrategyEnum.DELETE_ALL)
    public void getAllUsers_NoUsers() {
        List<User> users = userRepository.findAll();
        assertTrue("users list should be empty", users.isEmpty());
    }
}

UserRepositoryTest - Unit testing for Repository also working using fongo Reference - http://dontpanic.42.nl/2015/02/in-memory-mongodb-for-unit-and.html

package com.myapp.repository;

import com.myapp.config.SpringUnitTest;
import com.myapp.domain.User;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;


public class UserRepositoryTest extends SpringUnitTest {


    @Autowired
    private UserRepository userRepository;


    @Before
    public void setup() {
        importJSON("user", "user/user.json");
    }

    @Test
    //@UsingDataSet(loadStrategy = LoadStrategyEnum.CLEAN_INSERT, locations = "/json-data/user/user.json") // test/resources/..
    public void findUser_should_return_user() {
        User user = userRepository.findByXYZId("XX12345");
        assertNotNull(user);
    }

    @Test
    public void findUser_should_return_null() {
        User user = userRepository.findByXYZId("XX99999");
        assertNull(user);
    }

    @Test
    public void deleteUser_should_return_null() {
        userRepository.delete("XX12345");
        User user = userRepository.findByXYZId("XX12345");
        assertNull(user);
    }

    @Test
    public void saveUser_should_return_user() {
        User user = new User();
        user.setXYZId("XX12345");
        user.setAck(true);
        List<DateTime> dateTimeList = new ArrayList<>();
        dateTimeList.add(DateTime.now(DateTimeZone.UTC));
        user.setAckOn(dateTimeList);
        User dbUser = userRepository.save(user);
        assertEquals(user, dbUser);
    }

    @Test
    public void findAllUser_should_return_users() {
        List<User> userList = userRepository.findAll();
        assertEquals(1, userList.size());
    }
}

Controller level testing not working.. Reference- https://www.paradigmadigital.com/dev/tests-integrados-spring-boot-fongo/

UserControllerTest failed java.lang.IllegalStateException: Failed to load ApplicationContext - At this point test mongo db details fetech instead of fongo test\resources\application.properties test server db details are loading

package com.myapp.config;

package com.myapp.controllers;

import com.myapp.config.FakeMongo;
import com.myapp.services.persistance.UserService;
import com.lordofthejars.nosqlunit.mongodb.MongoDbRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;

import static com.lordofthejars.nosqlunit.mongodb.MongoDbRule.MongoDbRuleBuilder.newMongoDbRule;
import static org.hamcrest.CoreMatchers.containsString;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ActiveProfiles("it")
@RunWith(SpringRunner.class)
@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    classes =  Application.class
)
@Import(value = {FakeMongo.class})
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application-it.properties")
public class UserControllerTest {


    @Rule
    public MongoDbRule embeddedMongoDbRule = newMongoDbRule().defaultSpringMongoDb("mockDB");

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService service;

    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void deleteUser() throws Exception {
        Mockito.when(this.service.deleteUser(Mockito.anyString())).thenReturn(true);
        this.mockMvc.perform(delete("/User")).andDo(print()).andExpect(status().isOk())
                .andExpect((ResultMatcher) content().string(containsString("true")));
    }
}

UserControllerTest Not working, failing with error java.lang.IllegalStateException: Failed to load ApplicationContext as its tries to connect to test instance of mongo database using application.properties present in test/resources

Appreciate working example to use fakemongo while running Integration test for Controller level

What changes, I need to do in code level(Controller class or any other class) or application.properties of test\resources ?

StackOverFlow
  • 4,486
  • 12
  • 52
  • 87
  • 1
    Would you post a minimum reproducible sample as a project on GitHub? I try to clone, run it an discover out what did go wrong. – Nikolas Charalambidis Aug 11 '20 at 18:14
  • Are you sure that you're running your test with this parameter: -Dspring.profiles.active=it . Can you share the line in the log including this line : "The following profiles are active" – gungor Aug 12 '20 at 20:18
  • @gungor - While running individual/bulk test, I am not passing any parameter. What changes need to do in pom.xml so while running integration test pickup specific profile? Any input plz – StackOverFlow Aug 15 '20 at 08:46
  • Can you post spring log, especially containing the line "The following profiles are active"? Actually it should have picked the correct properties file when @ActiveProfiles("it") set. – gungor Aug 15 '20 at 09:52

0 Answers0