Итак, у меня есть класс:
@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
должен быть откат.