我需要测试此服务的回滚方案:
@Service
public class MyService2 {
private final Entity2Repo entity2Repo;
public MyService2(Entity2Repo entity2Repo) {
this.entity2Repo = entity2Repo;
}
public void create(Long entity1Id) {
Entity2 entity2 = new Entity2();
entity2.assignToEntity1(entity1Id);
entity2Repo.save(entity2);
}
}
我已经创建了这个集成测试用例:
@Transactional
@RunWith(SpringRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class MyServiceIntTest {
@Autowired
private Entity1Repo entity1Repo;
@Autowired
private EntityManager entityManager;
@Test
public void create() throws Exception {
MyService2 mock = mock(MyService2.class);
doThrow(new RuntimeException("bla bla")).when(mock).create(anyLong());
MyService myService = new MyService(entity1Repo, mock);
try {
myService.create("some name");
fail("should never fails");
} catch (RuntimeException e) {
assertThat(e.getMessage()).isEqualTo("bla bla"); // success
}
Entity1 dbEntity1 = (Entity1) entityManager.createQuery("from Entity1 where name = 'some name'").getSingleResult();
assertThat(dbEntity1).isNull(); // fail, however it should be null as it is rolled-back
}
}
问题是,为什么组织对象在回滚发生后仍然保存在数据库中?
编辑:github上的完整源代码:https://github.com/mhewedy-playground/test-transaction-rollback
答案 0 :(得分:-1)
问题是,我是在弹簧上下文中创建MyService
对象,然后期望事务管理器启动。
我已将测试代码更改为以下内容,现在它已成功运行:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class MyServiceIntTest {
@Autowired
private EntityManager entityManager;
@Autowired
private MyService myService;
@MockBean
private MyService2 myService2;
@Transactional
@Test(expected = RuntimeException.class)
public void createWillRollback() throws Exception {
doThrow(new RuntimeException("bla bla")).when(myService2).create(anyLong());
myService.create("some name");
assertThat(count()).isEqualTo(0);
}
@Transactional
@Test
public void create() throws Exception {
doNothing().when(myService2).create(anyLong());
myService.create("some name");
assertThat(count()).isEqualTo(1);
}
private long count() {
return ((Long) entityManager.createQuery("select count(*) from Entity1").getSingleResult());
}
}