#java #spring #spring-boot #junit #rollback
Вопрос:
Я использую @Transactional для отката при возникновении ошибки. Чтобы убедиться, что эта аннотация работает, я хочу протестировать ее с помощью Junit. Мой код прост. Просто сохраните данные, повторяя 100 данных, используя метод сохранения jpa. Когда метод itemSave дважды повторяет метод saveAll, я хочу создать исключение во время выполнения и убедиться, что таблица элементов откатана и содержимое таблицы соответствует ожиданиям. ————Класс обслуживания—————————
@Slf4j
@Service
public class SampleService {
@Autowired
SampleLogic sampleLogic;
@Transactional
public CommandType execute() {
try {
//get items
List<ItemEntity> itemEntities = sampleLogic.getItems();
//save item data
sampleLogic.itemSave(itemEntities);
} catch (Exception e) {
log.error("Error Happened!!!", e);
return CommandType.FAILURE;
}
return CommandType.SUCCESS;
}
}
——логический класс—————————————-
@Component
public class SampleLogic {
@Autowired
SampleRepository sampleRepository;
public List<ItemEntity> getItems() {
List<ItemEntity> itemEntities = new ArrayList<>();
for(int i = 0; i < 1000; i ) {
itemEntities.add(new ItemEntity(String.valueOf(i), "itemName"));
}
return itemEntities;
}
public void itemSave(List<ItemEntity> itemEntities) {
Iterables.partition(itemEntities, 100).forEach(list -> {
// save data per 100
sampleRepository.saveAll(itemEntities);
});
}
}
——тестовый класс—————————————-
@ExtendWith(SpringExtension.class)
@TestExecutionListeners({DirtiesContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
TransactionDbUnitTestExecutionListener.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class SampleServiceTest {
@InjectMocks
private SampleService sampleService;
@Test
@DatabaseSetup("/itemPrep.xml")
@ExpectedDatabase(value = "/testdata/CustomerServiceTest/init-data", assertionMode=DatabaseAssertionMode.NON_STRICT)
void whenSaveMethodCalledRollBackHappen() {
//
//make sure execute method returns failure and item table is roll backed
Assertions.assertEquals(CommandType.FAILURE, sampleService.execute());
}
}
I was thinking to insert 100 data first, and when 101st data is inserted, runtime exception is thrown and rollback happens. But I couldn’t make it happen…
I wonder if this could work, or there is any other way to test if roll back happens in this codes.
@Test
@DatabaseSetup("/itemPrep.xml")
@ExpectedDatabase(value = "/testdata/CustomerServiceTest/init-data", assertionMode=DatabaseAssertionMode.NON_STRICT)
void whenSaveMethodCalledRollBackHappen() {
//
List<ItemEntity> itemMockList = Mockito.mock(List.class);
for(int i = 0; i < 100; i ) {
Mockito.when(itemMockList.get(i))
.thenReturn(new ItemEntity(String.valueOf(i), "itemName"));
}
Mockito.when(itemMockList.get(101)).thenThrow(new RuntimeException());
//make sure execute method returns failure and item table is roll backed
Assertions.assertEquals(CommandType.FAILURE, sampleService.execute());
}