Ich schreibe Komponententests für meinen Service. Das Problem besteht darin, dass Transaktionen nach Abschluss des Tests nicht automatisch durch den Spring-Boot-Vorgang zurückgesetzt werden.Spring Boot, Transaktion ist kein Rollback nach Test
Hier ist meine Tests:
@SpringApplicationConfiguration(classes = { TestApplicationConfiguration.class, TestDataSourceConfiguration.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class BoardServiceTest {
@Autowired
private UserService userService;
@Autowired
private CardService cardService;
@Autowired
private BoardCardService boardCardService;
@Autowired
private BoardService boardService;
@Autowired
private CommonBoardService commonBoardService;
@Autowired
private AuthorityService authorityService;
@Test(expected = CommonException.class)
@Transactional
public void testCreateBoardStatusAFK() {
final User admin = userService.findUserById(1l);
admin.setCurrentBoard(null);
Board board = boardService.startBoard(admin);
assertEquals(board, admin.getCurrentBoard());
// Board has status IN_PROGRESS, current time < timeToComplete
board.setSelectedCardsCount(boardService.getDefaultCardsToSelectCount() - 1);
board.setTimeToComplete(DateUtils.addHours(new Date(), boardService.getDefaultMinsToComplete()));
board = commonBoardService.save(board);
board = boardService.startBoard(admin);
assertEquals(admin.getCurrentBoard().getStatus(), Board.IN_PROGRESS);
// Board has status IN_PROGRESS, current time > timeToComplete
board.setTimeToComplete(DateUtils.addHours(new Date(), -1));
board = commonBoardService.save(board);
board = boardService.startBoard(admin);
assertEquals(admin.getCurrentBoard().getStatus(), Board.AFK);
}
}
Nach der Testdurchführung, die entsprechende Tabelle in Test db durch neuen Rekord aufgefüllt.
Bitte, sagen Sie mir, wie dieses Problem zu lösen?
Update:
Hier ist die Umsetzung meiner Service-Methode, dass während des Tests aufgerufen wird:
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Board update(Board board, Date finishedDate, Integer status) {
board.setStatus(status);
board.setFinishedDate(finishedDate);
return boardRepository.save(board);
}
Wie können Sie sehen, neue Transaktion geöffnet wird, wenn diese Methode aufgerufen wird. In meiner Debug-Konsole sehe ich die folgenden Informationen, nach der Aktualisierung abgeschlossen ist:
Hibernate: select nextval ('boards_id_seq')
Hibernate: insert into boards (created_date, updated_date, cards_to_hold, cards_to_select, finished_date, holded_cards_count, selected_cards_count, started_date, status, time_to_complete, time_to_next_board, user_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Ich verstehe nicht, warum Hibernate neue Einheit in db erstellen, obwohl ich einen bestehenden bin zu aktualisieren. Also, vielleicht ist das der Grund für ein solches Verhalten?
Wenn Sie einen Komponententest schreiben, würde es nicht einfacher machen, wenn Sie die Klassen verspotten, die Dinge in der Datenbank speichern? (Wie ein Repository, Entitymanager, ...) – g00glen00b
@ g00glen00b, Nun, wie der Frühling die Transaktionen in Tests verwaltet, deshalb möchte ich andere Komponenten nicht verspotten. –
Grüße zum Zurückrollen im Test. Sie können Ihre Testklasse mit ** @ TransactionConfiguration (defaultRollback = true) ** kommentieren. Dies führt dazu, dass die Transaktion immer zurückgesetzt wird. Beschriften Sie auch die Testklasse mit ** @ Transactional **, um sicherzustellen, dass alle Tests zurückgesetzt werden –