我正在撰寫一個集成測驗,用@SpringBootTest.
假設我使用測驗中的純 SQL 創建了一些產品,呼叫基于它進行一些計算的計算服務,并呼叫另一個服務將這些計算結果保存在不同的表中。
什么我需要的是所有回滾所做的更改測驗結束后。
我閱讀了不同的問題,嘗試@Transactional在課堂或測驗方法中使用。
試圖放置資料庫屬性autocommit=false。
試圖將SqlSession物件和Spy它@Before放入服務中,將資料保存到不同的表中并將其回滾到@After. 此外,嘗試使用Connectionwithautocommit=false但它不起作用,無論如何都是不同的交易。
該@Repository豆類也標注了@Mapper,因為我們使用My-Batis。似乎my-batis每當呼叫映射器時都會創建新事務。
所以我剩下的唯一想法是啟動記憶體資料庫進行集成測驗并使用它。或者我可能遺漏了一些東西,可以通過交易管理以其他方式完成?
我如何在一個事務中執行所有呼叫,以便他們看到所做的更改并在之后回滾它?
這是我正在嘗試執行的測驗的示例代碼:
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MyTestClass {
@Autowired
private DataRepository dataRepository;
@Autowired
private CalculateService calculateService;
@Before
public void setUp() throws SQLException {
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
connection = session.getConnection();
connection.setAutoCommit(false);
spySession = Mockito.spy(session);
// other stuff with SqlSessionFactory mocking and injecting the mock
}
@After
public void cleanUp() {
spySession.rollback();
}
@Test
public void myTest(){
ResultSet resultSet = connection.prepareStatement("Insert into...").executeQuery(); // create new product
resultSet.next();
String createdProductId = resultSet.getString(1);
Product createdProduct = dataRepository.getProduct(createdProductId);
assertNotNull(createdProduct); // fails here
calculateService.calculate(createdProduct); // this call creates new threads there
// and calls other service that saves data in different trasaction aswell
createdProduct = dataRepository.getProduct(createdProductId); // call again to assert calculation results
assertSomeField(createdProduct.getSomeField);
// other assertions here
}
}
uj5u.com熱心網友回復:
一段時間后,我找到了解決此問題的方法。它不是sofisticated和beatifull,我會說它有點難看但它有效。
MybatisSqlSession有一個方法getMapper,使用它你可以獲得一個映射器來查看當前事務中所做的更改,它看起來像這樣:
DataRepository dataRepository = session.getMapper(DataRepository.class);
所以我得到了我需要的所有映射器,并使用ReflectionTestUtils.setField.
SqlSession本身在帶@After注釋的方法中回滾。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/355615.html
