Spring Data MongoDB — это проект в рамках проекта Spring Data, который предоставляет расширение модели программирования Spring для написания приложений, использующих MongoDB в качестве базы данных.
Чтобы писать тесты с использованием NoSQLUnit для приложений Spring Data MongoDB , вам не нужно ничего особенного, кроме того, что Spring Data MongoDB использует специальное свойство _class
для хранения информации о типе вместе с документом.
_class
хранит полное имя класса внутри документа для документа верхнего уровня, а также для каждого значения, если оно является сложным типом.
Тип сопоставления
MappingMongoConverter
используется в качестве реализации сопоставления типов по умолчанию, но вы можете настроить еще больше, используя @TypeAlias
или реализацию интерфейса TypeInformationMapper
.
заявка
Звездный Флот попросил нас разработать приложение для хранения всех журналов членов экипажа корабля в их системах. Для реализации этого требования мы будем использовать базу данных MongoDB в качестве бэкэнд-системы и Spring Data MongoDB на уровне персистентности.
Лог- документы имеют следующий формат json :
Пример документа журнала
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
{ "_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- класса, один для всего документа и другой для обычной части.
Звездный класс
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@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 } |
Лог класс
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@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
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
@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; } } |
файл контекста приложения
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://www.springframework.org/schema/beans < context:component-scan base-package = "com.lordofthejars.nosqlunit.springdata.mongodb" /> < context:annotation-config /> </ beans > |
В этом примере мы использовали класс MongoTemplate
для доступа к MongoDB, чтобы не создавать слишком сложный пример, но в более CrudRepository
проекте я рекомендую использовать подход Spring Data Repository путем реализации интерфейса CrudRepository
в классах менеджера.
тестирование
Как было сказано ранее, вам не нужно делать ничего особенного, кроме правильного использования свойства class
. Давайте посмотрим на набор данных, используемый для тестирования метода findAll, заполнив коллекцию _log базы данных журналов .
файл всех журналов
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
{ "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
что _class
свойства _class
установлено полное имя класса Log
.
Следующим шагом является настройка MongoTemplate
для выполнения теста.
LocalhostMongoAppConfig
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@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
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
@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 )); } } |
В предыдущем классе есть несколько важных моментов, на которые стоит обратить внимание:
- Поскольку NoSQLUnit использует правила JUnit, вы можете свободно использовать
@RunWith(SpringJUnit4ClassRunner)
. - Используя
@ActiveProfiles
мы загружаем тестовую конфигурацию вместо производственных. - Вы можете без проблем использовать Spring аннотации типа
@Autowired
.
Выводы
Не существует большой разницы между написанием тестов ни для одного Spring Data MongoDB и для приложений, которые его используют. Только помните, чтобы правильно _class
свойство _class
.
Ссылка: тестирование Spring-приложений MongoDB с NoSQLUnit от нашего партнера по JCG Алекса Сото в блоге One Jar To Rule All .