Ich verwende Spring Boot 1.4.0.M3.Die erwartete Ausnahme kann nicht getestet werden, wenn @Transactional mit @Commit verwendet wird
Ich habe ein @Entity
, dass ein username
hat, die eindeutig sein sollte:
@NotNull
@Column(unique = true)
@Pattern(regexp = "[a-zA-Z_\\-\\.0-9]+")
@Size(min = 1, max = 30)
private String username;
Mit einem Spring Data Repository, ich will es testen, ob eine Ausnahme sein, wenn ein doppelter Benutzername verwendet wird. Dieser Test funktioniert:
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository repository;
@Test(expected = DataIntegrityViolationException.class)
public void test() {
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
}
}
Wenn jedoch @Transactional
mit @Commit
Hinzufügen dieser Test fehlschlägt:
@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository repository;
@Test(expected = DataIntegrityViolationException.class)
@Commit
public void test() {
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
}
}
Aber ein Blick auf die Protokollierung wird die DataIntegrityViolationException
geworfen:
2016-05-24 09:05:16.619 ERROR 22790 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Unique index or primary key violation: "UK_D8HGQ87BS4VPMC81NQ9G69G8X_INDEX_D ON PUBLIC.MYPROJECT_USER(USERNAME) VALUES ('wim', 1)"; SQL statement: insert into myproject_user (password, username, role, id) values (?, ?, 'ADMIN', ?) [23505-191] 2016-05-24 09:05:16.620 INFO 22790 --- [
main] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements 2016-05-24 09:05:16.629 WARN 22790 --- [ main] o.s.test.context.TestContextManager
: Caught exception while allowing TestExecutionListener [org.springframew[email protected]589b3632] to process 'after' execution for test: method [public void com.spring.boot.test.user.UserRepositoryIntegrationTest.test()], instance [[email protected]], exception [java.lang.AssertionError: Expected exception: org.springframework.dao.DataIntegrityViolationException]
Warum Scheitert der Test? Könnte es sein, dass JUnit überprüft, ob die Ausnahme ausgelöst wird, bevor Spring die Transaktion festschreibt?
die als erwartet ist ... Die Ausnahme tritt nach der Transaktion zu begehen.Die Transaktion wird NACH dem Beenden der Methode ausgeführt. SO gibt es im Moment der Überprüfung keine Ausnahme. Sie haben damit das Verhalten des Tests geändert. Sie müssen innerhalb Ihrer Methode festlegen. –
"Ausnahme abgefangen, während TestExecutionListener erlaubt wurde", sagte alles. Sie möchten einen Commit ausführen, aber Sie möchten bestätigen, dass das Commit fehlschlägt. JUnit und Spring sind sich ihrer nicht bewusst, so dass Sie keine JUnit-Assertion für dieses Zeug verwenden können. Wie Martin sagte, benutze 'TestTransaction # end' in deinem Test. –
Danke für das Zeigen auf diese Klasse. Wusste nicht, dass es existiert. Ich habe eine Antwort mit der vollständigen Arbeitsversion hinzugefügt. –