mirror of
https://github.com/OtusTeam/Spring.git
synced 2026-05-30 10:50:42 +00:00
mongo-db-demo added
This commit is contained in:
@@ -4,4 +4,5 @@
|
||||
|
||||
* *unit-testing-plain-spring* - пример тестирования в проектах на чистом Spring
|
||||
* *unit-testing-spring-boot* - то же самое, только на Spring Boot
|
||||
* *hibernate-fetch-mode-demo* - демонстрация настроек Hibernate, в частности для решения проблемы N+1
|
||||
* *hibernate-fetch-mode-demo* - демонстрация настроек Hibernate, в частности для решения проблемы N+1
|
||||
* *mongo-db-demo* - демонстрация подходов к хранению вложенных сущностенй в MongoDB, работы с MongoEventListener, агрегациями и инструментом миграций Mongock
|
||||
@@ -0,0 +1,29 @@
|
||||
HELP.md
|
||||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@@ -0,0 +1,7 @@
|
||||
## Пример работы с MongoDB
|
||||
|
||||
В примере демонстрируется:
|
||||
* *два подхода к хранению вложенных сущностей*
|
||||
* *инициализация базы данными с помощью инструмента миграций Mongock*
|
||||
* *использование AbstractMongoEventListener для выполнения каскадных операций*
|
||||
* *работа с массивами с помощью агрегаций и Criteria api*
|
||||
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>ru.otus.example</groupId>
|
||||
<artifactId>mongo-db-demo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>mongo-db-demo</name>
|
||||
<description>Demo project for MongoDB</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.sourcre>1.8.</maven.compiler.sourcre>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.cloudyrock.mongock</groupId>
|
||||
<artifactId>mongock-spring</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>org.assertj.core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--Тестирование-->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.21.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>2.23.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.12.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package ru.otus.example.mongoDbDemo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties
|
||||
public class MongoDbDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MongoDbDemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package ru.otus.example.mongoDbDemo.changelogs;
|
||||
|
||||
import com.github.cloudyrock.mongock.ChangeLog;
|
||||
import com.github.cloudyrock.mongock.ChangeSet;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import lombok.val;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
import ru.otus.example.mongoDbDemo.model.Student;
|
||||
import ru.otus.example.mongoDbDemo.model.Teacher;
|
||||
|
||||
@ChangeLog(order = "001")
|
||||
public class InitMongoDBDataChangeLog {
|
||||
|
||||
private Knowledge springDataKnowledge;
|
||||
private Knowledge mongockKnowledge;
|
||||
private Knowledge aggregationApiKnowledge;
|
||||
|
||||
@ChangeSet(order = "000", id = "dropDB", author = "stvort", runAlways = true)
|
||||
public void dropDB(MongoDatabase database){
|
||||
database.drop();
|
||||
}
|
||||
|
||||
@ChangeSet(order = "001", id = "initKnowledges", author = "stvort", runAlways = true)
|
||||
public void initKnowledges(MongoTemplate template){
|
||||
springDataKnowledge = template.save(new Knowledge("Spring Data"));
|
||||
mongockKnowledge = template.save(new Knowledge("Mongock"));
|
||||
aggregationApiKnowledge = template.save(new Knowledge("AggregationApi"));
|
||||
}
|
||||
|
||||
@ChangeSet(order = "002", id = "initStudents", author = "stvort", runAlways = true)
|
||||
public void initStudents(MongoTemplate template){
|
||||
val student = new Student("Student #1", springDataKnowledge, mongockKnowledge);
|
||||
template.save(student);
|
||||
}
|
||||
|
||||
@ChangeSet(order = "003", id = "Teacher", author = "stvort", runAlways = true)
|
||||
public void initTeachers(MongoTemplate template){
|
||||
val teacher = new Teacher("Teacher #1", springDataKnowledge, mongockKnowledge, aggregationApiKnowledge);
|
||||
template.save(teacher);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.otus.example.mongoDbDemo.config;
|
||||
|
||||
import com.github.cloudyrock.mongock.Mongock;
|
||||
import com.github.cloudyrock.mongock.SpringMongockBuilder;
|
||||
import com.mongodb.MongoClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ApplicationConfig {
|
||||
|
||||
private static final String CHANGELOGS_PACKAGE = "ru.otus.example.mongoDbDemo.changelogs";
|
||||
|
||||
@Bean
|
||||
public Mongock mongock(MongoProps mongoProps, MongoClient mongoClient) {
|
||||
return new SpringMongockBuilder(mongoClient, mongoProps.getDatabase(), CHANGELOGS_PACKAGE)
|
||||
.setLockQuickConfig()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ru.otus.example.mongoDbDemo.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties("spring.data.mongodb")
|
||||
public class MongoProps {
|
||||
private int port;
|
||||
private String database;
|
||||
private String uri;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package ru.otus.example.mongoDbDemo.events;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterDeleteEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
import ru.otus.example.mongoDbDemo.repositories.StudentRepository;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MongoKnowledgeCascadeDeleteEventsListener extends AbstractMongoEventListener<Knowledge> {
|
||||
|
||||
private final StudentRepository studentRepository;
|
||||
|
||||
@Override
|
||||
public void onAfterDelete(AfterDeleteEvent<Knowledge> event) {
|
||||
super.onAfterDelete(event);
|
||||
val source = event.getSource();
|
||||
val id = source.get("_id").toString();
|
||||
studentRepository.removeExperienceArrayElementsById(id);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package ru.otus.example.mongoDbDemo.events;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.otus.example.mongoDbDemo.model.Student;
|
||||
import ru.otus.example.mongoDbDemo.repositories.KnowledgeRepository;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MongoStudentCascadeSaveEventsListener extends AbstractMongoEventListener<Student> {
|
||||
|
||||
private final KnowledgeRepository knowledgeRepository;
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(BeforeConvertEvent<Student> event) {
|
||||
super.onBeforeConvert(event);
|
||||
val student = event.getSource();
|
||||
if (student.getExperience() != null) {
|
||||
student.getExperience().stream().filter(e -> Objects.isNull(e.getId())).forEach(knowledgeRepository::save);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package ru.otus.example.mongoDbDemo.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Document
|
||||
public class Knowledge {
|
||||
@Id
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
public Knowledge(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package ru.otus.example.mongoDbDemo.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Document
|
||||
public class Student {
|
||||
@Id
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
@DBRef
|
||||
private List<Knowledge> experience;
|
||||
|
||||
public Student(String name, Knowledge... experience) {
|
||||
this.name = name;
|
||||
this.experience = Arrays.asList(experience);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package ru.otus.example.mongoDbDemo.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Document
|
||||
public class Teacher {
|
||||
@Id
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
private List<Knowledge> experience;
|
||||
|
||||
public Teacher(String name, Knowledge... experience) {
|
||||
this.name = name;
|
||||
this.experience = Arrays.asList(experience);
|
||||
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
|
||||
public interface KnowledgeRepository extends MongoRepository<Knowledge, String> {
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import ru.otus.example.mongoDbDemo.model.Student;
|
||||
|
||||
|
||||
public interface StudentRepository extends MongoRepository<Student, String>, StudentRepositoryCustom {
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
public interface StudentRepositoryCustom {
|
||||
long getExperienceArrayLengthByStudentId(String id);
|
||||
void removeExperienceArrayElementsById(String id);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import ru.otus.example.mongoDbDemo.model.Student;
|
||||
|
||||
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.where;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class StudentRepositoryCustomImpl implements StudentRepositoryCustom {
|
||||
|
||||
@Data
|
||||
private class ArraySizeProjection {
|
||||
private int size;
|
||||
}
|
||||
|
||||
private final MongoTemplate mongoTemplate;
|
||||
|
||||
public long getExperienceArrayLengthByStudentId(String id) {
|
||||
val aggregation = Aggregation.newAggregation(
|
||||
Aggregation.match(where("id").is(id)),
|
||||
Aggregation.project().andExclude("_id").and("experience").size().as("size"));
|
||||
|
||||
val arraySizeProjection = mongoTemplate.aggregate(aggregation, Student.class, ArraySizeProjection.class).getUniqueMappedResult();
|
||||
return arraySizeProjection == null ? 0 : arraySizeProjection.getSize();
|
||||
}
|
||||
|
||||
public void removeExperienceArrayElementsById(String id) {
|
||||
val query = Query.query(Criteria.where("$id").is(new ObjectId(id)));
|
||||
val update = new Update().pull("experience", query);
|
||||
mongoTemplate.updateMulti(new Query(), update, Student.class);
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import ru.otus.example.mongoDbDemo.model.Teacher;
|
||||
|
||||
public interface TeacherRepository extends MongoRepository<Teacher, String>, TeacherRepositoryCustom {
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TeacherRepositoryCustom {
|
||||
List<Knowledge> getTeacherExperienceById(String teacherId);
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
import ru.otus.example.mongoDbDemo.model.Teacher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class TeacherRepositoryCustomImpl implements TeacherRepositoryCustom {
|
||||
|
||||
private final MongoTemplate mongoTemplate;
|
||||
|
||||
@Override
|
||||
public List<Knowledge> getTeacherExperienceById(String teacherId) {
|
||||
val aggregation = newAggregation(
|
||||
match(Criteria.where("id").is(teacherId))
|
||||
, unwind("experience")
|
||||
, project().andExclude("_id").and("experience.id").as("_id").and("experience.name").as("name")
|
||||
);
|
||||
return mongoTemplate.aggregate(aggregation, Teacher.class, Knowledge.class).getMappedResults();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
spring:
|
||||
data:
|
||||
mongodb:
|
||||
uri: mongodb://localhost
|
||||
port: 27017
|
||||
database: test
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
@DataMongoTest
|
||||
@EnableConfigurationProperties
|
||||
@ComponentScan({"ru.otus.example.mongoDbDemo.config", "ru.otus.example.mongoDbDemo.repositories"})
|
||||
@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
|
||||
abstract class AbstractRepositoryTest {
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
@DisplayName("KnowledgeRepository при наличии listener-ов в контексте ")
|
||||
@ComponentScan("ru.otus.example.mongoDbDemo.events")
|
||||
class KnowledgeRepositoryWithListenerTest extends AbstractRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private KnowledgeRepository knowledgeRepository;
|
||||
|
||||
@Autowired
|
||||
private StudentRepository studentRepository;
|
||||
|
||||
@DisplayName("при удалении Knowledge должен удалить его из опыта студента")
|
||||
@Test
|
||||
void shouldRemoveKnowledgeFromStudentExperienceWhenRemovingKnowledge() {
|
||||
|
||||
// Загрузка студента и его пе
|
||||
val students = studentRepository.findAll();
|
||||
val student = students.get(0);
|
||||
val experience = student.getExperience();
|
||||
val firstKnowledge = experience.get(0);
|
||||
|
||||
knowledgeRepository.delete(firstKnowledge);
|
||||
|
||||
val expectedExperienceArrayLength = experience.size() - 1;
|
||||
val actualExperienceArrayLength = studentRepository.getExperienceArrayLengthByStudentId(student.getId());
|
||||
assertThat(actualExperienceArrayLength).isEqualTo(expectedExperienceArrayLength);
|
||||
|
||||
val actualStudentOptional = studentRepository.findById(student.getId());
|
||||
assertThat(actualStudentOptional.get().getExperience().size()).isEqualTo(expectedExperienceArrayLength);
|
||||
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
@DisplayName("KnowledgeRepository при отсутствии listener-ов в контексте ")
|
||||
class KnowledgeRepositoryWithoutListenerTest extends AbstractRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private KnowledgeRepository knowledgeRepository;
|
||||
|
||||
@Autowired
|
||||
private StudentRepository studentRepository;
|
||||
|
||||
@DisplayName("при удалении Knowledge не должен удалять его из опыта студента")
|
||||
@Test
|
||||
void shouldLeaveKnowledgeInStudentExperienceWhenRemovingKnowledge() {
|
||||
|
||||
// Загрузка студента и его пе
|
||||
val students = studentRepository.findAll();
|
||||
val student = students.get(0);
|
||||
val experience = student.getExperience();
|
||||
val firstKnowledge = experience.get(0);
|
||||
|
||||
knowledgeRepository.delete(firstKnowledge);
|
||||
|
||||
val expectedExperienceArrayLength = experience.size();
|
||||
val actualExperienceArrayLength = studentRepository.getExperienceArrayLengthByStudentId(student.getId());
|
||||
assertThat(actualExperienceArrayLength).isEqualTo(expectedExperienceArrayLength);
|
||||
|
||||
val actualStudentOptional = studentRepository.findById(student.getId());
|
||||
assertThat(actualStudentOptional.get().getExperience().size()).isNotEqualTo(expectedExperienceArrayLength);
|
||||
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
import ru.otus.example.mongoDbDemo.model.Student;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("StudentRepository при наличии listener-ов в контексте ")
|
||||
@ComponentScan("ru.otus.example.mongoDbDemo.events")
|
||||
class StudentRepositoryWithListenersTest extends AbstractRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private StudentRepository studentRepository;
|
||||
|
||||
@DisplayName("должен корректно сохранять студента с отсутствующими в БД знаниями")
|
||||
@Test
|
||||
void shouldCorrectSaveStudentWithNewKnowledge(){
|
||||
val student = new Student("Student #2", new Knowledge("Knowledge #3"));
|
||||
val actual = studentRepository.save(student);
|
||||
assertThat(actual.getId()).isNotNull();
|
||||
assertThat(actual.getName()).isEqualTo(student.getName());
|
||||
}
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
import ru.otus.example.mongoDbDemo.model.Student;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
@DisplayName("StudentRepository при отсутствии listener-ов в контексте ")
|
||||
class StudentRepositoryWithoutListenerTest extends AbstractRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private StudentRepository studentRepository;
|
||||
|
||||
@DisplayName("должен кидать MappingException во время сохранения студента с отсутствующими в БД знаниями")
|
||||
@Test
|
||||
void shouldThrowMappingExceptionWhenSaveStudentWithNewKnowledge(){
|
||||
val student = new Student("Student #2", new Knowledge("Knowledge #3"));
|
||||
assertThatThrownBy(() -> studentRepository.save(student)).isInstanceOf(MappingException.class);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package ru.otus.example.mongoDbDemo.repositories;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import ru.otus.example.mongoDbDemo.model.Knowledge;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("TeacherRepository должен ")
|
||||
class TeacherRepositoryTest extends AbstractRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private TeacherRepository teacherRepository;
|
||||
|
||||
@DisplayName(" возвращать корректный список знаний преподавателя")
|
||||
@Test
|
||||
void shouldReturnCorrectKnowledgeList(){
|
||||
val teachers = teacherRepository.findAll();
|
||||
val teacher = teachers.get(0);
|
||||
val experience = teacher.getExperience();
|
||||
assertThat(experience).isNotNull().hasSize(3);
|
||||
|
||||
val actualExperience = teacherRepository.getTeacherExperienceById(teacher.getId());
|
||||
assertThat(actualExperience).containsExactlyInAnyOrder(experience.toArray(new Knowledge[experience.size()]));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
spring:
|
||||
data:
|
||||
mongodb:
|
||||
port: 0
|
||||
database: test
|
||||
Reference in New Issue
Block a user