Статьи

Тестирование приложений Spring Data MongoDB с NoSQL Unit

Spring Data MongoDB

Spring Data MongoDB — это проект в рамках проекта
Spring Data, который предоставляет расширение
модели программирования
Spring для написания приложений, использующих
MongoDB в качестве базы данных.

Для написания тестов с использованием
NoSQLUnit для приложений
Spring Data MongoDB вам не нужно ничего особенного, кроме того, что
Spring Data MongoDB использует специальное свойство, вызываемое
_classдля хранения информации о типе вместе с документом.
_class Свойство хранит полное имя класса внутри документа для документа верхнего уровня, а также для каждого значения, если это сложный тип.
Запись Тип сопоставления

MappingMongoConverterиспользуется в качестве реализации отображения типов по умолчанию, но вы можете настроить еще больше, используя
@TypeAliasили реализуя
TypeInformationMapperинтерфейс.

заявка

Звездный Флот попросил нас разработать приложение для хранения всех журналов членов экипажа корабля в их системах.

Для реализации этого требования мы будем использовать
базу данных MongoDB в качестве бэкэнд-системы и
Spring Data MongoDB на уровне персистентности.
Лог- документы имеют следующий
формат
json :

Пример документа журнала

{
        "_class" : "com.lordofthejars.nosqlunit.springdata.mongodb.log.Log" ,
        "_id" : 1 ,
        "owner" : "Captain" ,
        "stardate" : {
                "century" : 4 ,
                "season" : 3 ,
                "sequence" : 125 ,
                "day" : 8
        } ,
        "messages" : [
                        "We have entered a spectacular binary star system in the Kavis Alpha sector on a most critical mission of astrophysical research. Our eminent guest, Dr. Paul Stubbs, will attempt to study the decay of neutronium expelled at relativistic speeds from a massive stellar explosion which will occur here in a matter of hours." ,
                        "Our computer core has clearly been tampered with and yet there is no sign of a breach of security on board. We have engines back and will attempt to complete our mission. But without a reliable computer, Dr. Stubbs' experiment is in serious jeopardy."
        ]
}

Этот документ моделируется на два
Java- класса, один для всего документа, а другой для обычной части.
Звездный класс


@Document
public class Stardate {

        private int century;
        private int season;
        private int sequence;
        private int day;

        public static final Stardate createStardate(int century, int season, int sequence, int day) {

                Stardate stardate = new Stardate();

                stardate.setCentury(century);
                stardate.setSeason(season);
                stardate.setSequence(sequence);
                stardate.setDay(day);

                return stardate;

        }

        //Getters and Setters
}

@Document
public class Stardate {

        private int century;
        private int season;
        private int sequence;
        private int day;

        public static final Stardate createStardate(int century, int season, int sequence, int day) {

                Stardate stardate = new Stardate();

                stardate.setCentury(century);
                stardate.setSeason(season);
                stardate.setSequence(sequence);
                stardate.setDay(day);

                return stardate;

        }

        //Getters and Setters
}

Лог класс

@Document
public class Log {

        @Id
        private int logId;

        private String owner;
        private Stardate stardate;

        private List<String> messages = new ArrayList<String>();

        //Getters and Setters
}


Помимо классов моделей нам также необходим класс DAO для реализации операций CRUD и
 файл
контекста приложения Spring .

Класс MongoLogManager

@Repository
public class MongoLogManager implements LogManager {

        private MongoTemplate mongoTemplate;

        public void create(Log log) {
                this.mongoTemplate.insert(log);
        }

        public List<Log> findAll() {
                return this.mongoTemplate.findAll(Log.class);
        }

        @Autowired
        public void setMongoTemplate(MongoTemplate mongoTemplate) {
                this.mongoTemplate = mongoTemplate;
        }

}

@Repository
public class MongoLogManager implements LogManager {

        private MongoTemplate mongoTemplate;

        public void create(Log log) {
                this.mongoTemplate.insert(log);
        }

        public List<Log> findAll() {
                return this.mongoTemplate.findAll(Log.class);
        }

        @Autowired
        public void setMongoTemplate(MongoTemplate mongoTemplate) {
                this.mongoTemplate = mongoTemplate;
        }

}

файл контекста приложения

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd">

     <context:component-scan base-package="com.lordofthejars.nosqlunit.springdata.mongodb"/>
     <context:annotation-config/>

</beans>

Наконечник

В этом примере мы использовали
MongoTemplateкласс для доступа к
MongoDB, чтобы не создавать слишком сложный пример, но в более крупном проекте я рекомендую использовать
подход
Spring Data Repository , реализуя
CrudRepositoryинтерфейс на классах менеджера.

тестирование


Как было сказано ранее, вам не нужно делать ничего особенного, кроме
classправильного использования
свойства. Давайте посмотрим на набор данных, используемый для тестирования
findAllметода, заполнив _log коллекцию
базы данных
logs .

файл всех журналов

{
        "log":[
                {
                        "_class" : "com.lordofthejars.nosqlunit.springdata.mongodb.log.Log" ,
                        "_id" : 1 ,
                        "owner" : "Captain" ,
                        "stardate" : {
                                "century" : 4 ,
                                "season" : 3 ,
                                "sequence" : 125 ,
                                "day" : 8
                        } ,
                        "messages" : [
                                "We have entered a spectacular binary star system in the Kavis Alpha sector on a most critical mission of astrophysical research. Our eminent guest, Dr. Paul Stubbs, will attempt to study the decay of neutronium expelled at relativistic speeds from a massive stellar explosion which will occur here in a matter of hours." ,
                                "Our computer core has clearly been tampered with and yet there is no sign of a breach of security on board. We have engines back and will attempt to complete our mission. But without a reliable computer, Dr. Stubbs' experiment is in serious jeopardy."
                        ]
                }
                ,
                {
                        "_class" : "com.lordofthejars.nosqlunit.springdata.mongodb.log.Log" ,
                        "_id" : 2 ,
                        "owner" : "Captain" ,
                        "stardate" : {
                                "century" : 4 ,
                                "season" : 3 ,
                                "sequence" : 152 ,
                                "day" : 4
                        } ,
                        "messages" : [
                                "We are cautiously entering the Delta Rana star system three days after receiving a distress call from the Federation colony on its fourth planet. The garbled transmission reported the colony under attack from an unidentified spacecraft. Our mission is one of rescue and, if necessary, confrontation with a hostile force."
                        ]
                }
                ...
}


Смотрите, что для
_classсвойства установлено полное имя
Logкласса.

Следующим шагом является настройка
MongoTemplateдля выполнения теста.

LocalhostMongoAppConfig

@Configuration
@Profile("test")
public class LocalhostMongoAppConfig {

        private static final String DATABASE_NAME = "logs";

        public @Bean Mongo mongo() throws UnknownHostException, MongoException {
                Mongo mongo = new Mongo("localhost");
                return mongo;
        }

        public @Bean MongoTemplate mongoTemplate() throws UnknownHostException, MongoException {
                MongoTemplate mongoTemplate = new MongoTemplate(mongo(), DATABASE_NAME);
                return mongoTemplate;
        }

}


Обратите внимание, что этот
MongoTemplateобъект будет создан только при
активном
тестовом профиле.

И теперь мы можем написать
тестовый пример
JUnit :

WhenAlmiralWantsToReadLogs

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:com/lordofthejars/nosqlunit/springdata/mongodb/log/application-context-test.xml")
@ActiveProfiles("test")
@UsingDataSet(locations = "all-logs.json", loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
public class WhenAlmiralWantsToReadLogs {

        @ClassRule
        public static ManagedMongoDb managedMongoDb = newManagedMongoDbRule()
                        .mongodPath(
                                        "/Users/alexsotobueno/Applications/mongodb-osx-x86_64-2.0.5")
                        .build();

        @Rule
        public MongoDbRule mongoDbRule = newMongoDbRule().defaultManagedMongoDb("logs");

        @Autowired
        private LogManager logManager;

        @Test
        public void all_entries_should_be_loaded() {

                List<Log> allLogs = logManager.findAll();
                assertThat(allLogs, hasSize(3));

        }

}


В предыдущем классе есть несколько важных моментов, на которые стоит обратить внимание:

  1. Поскольку
    NoSQLUnit использует
    правила JUnit, вы можете использовать их
    @RunWith(SpringJUnit4ClassRunner)свободно.

  2. Используя
    @ActiveProfilesмы загружаем тестовую конфигурацию вместо производственных.

  3. Вы можете использовать
    Spring аннотации, как
    @Autowiredбез проблем.

Выводы


Не существует большой разницы между написанием тестов ни для одного
Spring Data MongoDB и для приложений, которые его используют. Только имейте в виду, чтобы правильно определить
_classсвойство.

Мы продолжаем учиться,

Алекс.


Els astronautes volen baix, Els núvols passen com qui no di res.
Amb les butxaques a les mans, Caminarem els passos d’altres peus. (Па ам Оли и Сал — Блаумут)