сервиса, которые добавляют/удаляют в энтити новую роль (и есесно записывают через хибер в БД). В рантайме всё замечательно работает.
Пишу тесты на сервис: создаю тестового юзера, записываю в БД, выполняю тестируемый метод, делаю проверки.
По отдельности тесты работают ок, но т.к. тест-кейсов более одного, то БД не даёт сохранить тестового юзера на втором и далее тесте, т.к. уже нет уникальности.
Тогда вешаю @Transactional на класс тестов, чтобы изменения после откатывались метода откатывались (в других тест-классах проекта реализовано так же).
НО тогда в моменте user.getRoles().add(role) получаю:
java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:75)
at org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:211)
Где искать зарытую собаку?
1. Общую Transactional нужно убрать - по моему это боьшое зло и код будет отрабатывать иначе - что-то будет доставаться из кэша ИМЕННО В ТЕСТАХ - где-то это будет один и тот же обьект и полезут всякие артифакты. 2. Может в конце каждого теста - чистить сущности просто
Какую именно коллекцию ты сохраняешь как роли у юзера? Если List.of то она неизменяемая и обычно у неё такие ошибки летят
Ещё говорят что правильно делать так чтобы тесты никак не влияли друг на друга по этому по хорошему тебе нужен свой уникальный пользователь для каждого теста
в сервисе нет метода удаления юзера, придётся подключать UserDao и делать это напрямую, но это вариант. сейчас попробую.
роли достаются через дао юзера: User user = userDao.getById(userId); user.getRoles().add(role); само поле - простой Set<AccessRole> https://pastebin.com/ieyzaHb5
возможно. попробовал генерить случайных юзеров и конечно заработало без Transactional
Посмотри какая именно коллекция у roles в дебаге, уже просто интересно) Ну если не сложно)
По-хорошему тест обязан подчищать за собой
ну вот это и было реализовано через Transactional, судя по другим тест-классам, которые писались не мной, применил такую же логику и получил такое
можешь попробовать делать entityManager.clear() между тестами чтобы быть уверенным что ничего из кеша не прилетает
PersistentSet ну собсно это и было в стеке: at org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:211) опять же.. в рантайме то всё ок, а при наличии Transactional началось...
для этого есть @DirtiesContext
Обсуждают сегодня