Conversation
- Методы выборки из таблицы книг.
- Добавление Spring Shell.
- Добавление Shell команд.
- Разделение методов на отдельные модули. - Добавление тестов.
- Изменены запросы книг. - Добавление внешних ключей для таблицы книг. - Изменение сущности Book. - Изменение типа id.
- Использование @jdbcTest.
- Изменение тестов.
- Доработка тестов.
- Связи OneToOne изменены на ManyToOne.
# Conflicts: # README.md # src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java # src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java # src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java
- Доработка скриптов.
- Добавление классов для обработки сущности Comment и покрытие тестами.
# Conflicts: # README.md # src/main/java/ru/otus/mkulikov/Application.java # src/main/java/ru/otus/mkulikov/app/dao/AuthorDao.java # src/main/java/ru/otus/mkulikov/app/dao/AuthorDaoJpa.java # src/main/java/ru/otus/mkulikov/app/dao/GenreDao.java # src/main/java/ru/otus/mkulikov/app/dao/GenreDaoJpa.java # src/main/java/ru/otus/mkulikov/app/service/AuthorManageServiceImpl.java # src/main/java/ru/otus/mkulikov/app/service/BookManageSeviceImpl.java # src/main/java/ru/otus/mkulikov/app/service/GenreManageServiceImpl.java # src/test/java/ru/otus/mkulikov/app/dao/AuthorDaoJpaTest.java # src/test/java/ru/otus/mkulikov/app/dao/BookDaoJpaTest.java # src/test/java/ru/otus/mkulikov/app/dao/GenreDaoJpaTest.java # src/test/resources/schema-test.sql
- Подключение liquibase.
| */ | ||
|
|
||
| @DisplayName("Класс AuthorDaoJpa") | ||
| @RunWith(SpringRunner.class) |
There was a problem hiding this comment.
Это не нужно (во всех тестах). Это для 4го JUnit. У вас JUnit5. Для него используется @ExtendWith({SpringExtension.class}), а он есть внутри @DataJpaTest
| @ComponentScan("ru.otus.mkulikov.app") | ||
| @DataJpaTest | ||
| @TestPropertySource(locations= "classpath:application.yml") | ||
| class AuthorManageSeviceImplTest { |
There was a problem hiding this comment.
Сервисы лучше тестировать безотносительно к БД, замокав Dao слой
|
|
||
| Book getById(long id); | ||
|
|
||
| List<Book> getAllObjects(); |
There was a problem hiding this comment.
Если кастомный репозиторий сделан, чтобы решить N+1 проблему, то аналогичного результата, но с меньшим количеством кода, можно добиться с помощью использования @NamedEntityGraph
| @Repository | ||
| public interface BookDaoCustom<T extends Book> { | ||
|
|
||
| Book getById(long id); |
There was a problem hiding this comment.
Лучше вернуть Optional. Хотя бы даже для единообразия с JpaRepository
|
|
||
| @Override | ||
| public long addBook(String caption, long authorId, long genreId, String description) { | ||
| Author author = authorDao.findById(authorId).get(); |
There was a problem hiding this comment.
Тут и в других местах. Лучше использовать возможности Optional. Вместо get можно сделать orElseThrow или orElse/orElseGet.
|
|
||
| assertAll( | ||
| "author", | ||
| () -> assertNotNull(author.get()), |
There was a problem hiding this comment.
Для проверки Optional хорошо подходит assertThat из AssertJ
| @DisplayName("Удаление автора, который используется в таблице книг") | ||
| void deleteObject() { | ||
| authorDao.deleteById(1L); | ||
| //assertThat(authorDao.count()).isEqualTo(1); |
There was a problem hiding this comment.
Над @DataJpaTest висит @Transactional. В тестах это значит, что все внутри метода будет выполнятся в транзакции, которая будет откачена после метода. Поэтому если хотите убедиться, что удаление автора не сработало это нужно делать как-то так
@Test
@DisplayName("Удаление автора, который используется в таблице книг")
@Transactional(propagation = Propagation.NOT_SUPPORTED)
void deleteObject() {
assertThrows(DataIntegrityViolationException.class, () -> authorDao.deleteById(1L));
assertThat(authorDao.count()).isEqualTo(3);
}
- Возвращаю Optional в DAO.
- Использование @NamedEntityGraph.
| @DataJpaTest | ||
| @DisplayName("Класс AuthorDaoJpa") | ||
| @ComponentScan("ru.otus.mkulikov.app") | ||
| @TestPropertySource(locations= "classpath:application.yml") |
There was a problem hiding this comment.
Все работает без @ComponentScan и @TestPropertySource
| */ | ||
|
|
||
| @DisplayName("Класс AuthorManageSevice") | ||
| @TestPropertySource(locations= "classpath:application.yml") |
There was a problem hiding this comment.
Тут @TestPropertySource вроде как тоже не нужно. Ну и можно тестировать через @SpringBootTest, чтобы из контекста бины доставать (в т.ч. моки). Так как у вас конечно даже лучше) Но у нас курс по спрингу. Желательно пробовать чаще использовать его (спринга) технологии
|
|
||
| @Repository | ||
| public interface BookDao extends JpaRepository<Book, Long>, BookDaoCustom<Book> { | ||
|
|
There was a problem hiding this comment.
@EntityGraph("BookGraph")
List<Book> findAll();
@EntityGraph("BookGraph")
Optional<Book> findById(long id);
| @Transactional(propagation = Propagation.NOT_SUPPORTED) | ||
| void deleteObject() { | ||
| assertThrows(DataIntegrityViolationException.class, () -> authorDao.deleteById(1L)); | ||
| assertThat(authorDao.count()).isEqualTo(3); |
There was a problem hiding this comment.
Магические числа и строки лучше сделать константами
| assertAll( | ||
| "author", | ||
| () -> assertNotNull(author_selected), | ||
| () -> assertEquals(4, author_selected.orElse(null).getId()), |
No description provided.