【发布时间】:2020-01-31 08:46:37
【问题描述】:
所以我有课:
@Service
public class MyService {
@Autowired
private RepositoryA repoA;
@Autowired
private RepositoryB repoB;
@Transactional
public void storeEntity(SomeEntity e) {
repoA.save(e);
OtherEntity o = doSomethingWithEntity(e);
repoB.save(o);
}
}
我的方法storeEntity 两次保存到两个不同的数据源。我希望如果保存到 repoB 失败,或者 doSomethingWithEntity 失败,repoA.save(e) 将被回滚。
我想编写一个小测试来确保这种行为:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceForTransactionTest {
@Autowired
private MyService subject;
@Autowired
private RepositoryA repoA;
@MockBean
private RepositoryB repoB;
@Test
public void repoBShouldNotHaveEntries() {
// given
when(repoB.save(any())).thenThrow(new IllegalStateException("Something wrong with db"));
assertThat(repoB.count()).isEqualTo(0);
// when
SomeEntity e = ...
subject.storeEntity(e);
// then
assertThat(repoA.count()).isEqualTo(0);
}
}
这不起作用,因为抛出异常并且测试失败。当我用 try/catch 包围调用时,我的断言失败,并显示 repoA 有 1 个条目的消息。如何解决这个问题?
我也试过这个:
@Test
public void repoBShouldNotHaveEntries() {
// given
when(repoB.save(any())).thenThrow(new IllegalStateException("Something wrong with db"));
assertThat(repoB.count()).isEqualTo(0);
// when
SomeEntity e = ...
try {
subject.storeEntity(e);
} catch (Exception e) {
// some output here
}
// then
assertThat(repoA.count()).isEqualTo(0);
}
断言失败。我也试过这个:
@Test
public void repoBShouldNotHaveEntries() {
// given
when(repoB.save(any())).thenThrow(new IllegalStateException("Something wrong with db"));
assertThat(repoB.count()).isEqualTo(0);
// when
SomeEntity e = ...
subject.storeEntity(e);
}
@After
public void tearDown() {
// then
assertThat(repoA.count()).isEqualTo(0);
}
}
同样失败。找到了 1 条记录,但我希望 @Transactional 应该回滚。
【问题讨论】:
-
尝试在测试方法中添加@Transactional
标签: java junit transactions spring-transactions