如何在春季测试回滚方案

时间:2018-04-04 06:37:59

标签: spring spring-data-jpa transactional

我需要测试此服务的回滚方案:

@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

1 个答案:

答案 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());
    }
}
相关问题