wake-up-neo.com

Rollback-Transaktion nach @Test

Zunächst habe ich auf StackOverflow viele Threads zu diesem Thema gefunden, aber keiner hat mir wirklich geholfen. Es tut mir leid, dass ich möglicherweise doppelte Fragen gestellt habe.

Ich führe JUnit-Tests mit Spring-Test aus. Mein Code sieht so aus

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {})
public class StudentSystemTest {

    @Autowired
    private StudentSystem studentSystem;

    @Before
    public void initTest() {
    // set up the database, create basic structure for testing
    }

    @Test
    public void test1() {
    }    
    ...  
}

Mein Problem ist, dass ich möchte, dass meine Tests andere Tests NICHT beeinflussen. Also möchte ich für jeden Test so etwas wie ein Rollback erstellen. Ich habe viel danach gesucht, aber bisher nichts gefunden. Ich benutze dafür Hibernate und MySql

65
Jan Vorcak

Fügen Sie einfach die Anmerkung @Transactional Zu Ihrem Test hinzu:

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {"testContext.xml"})
@Transactional
public class StudentSystemTest {

Standardmäßig startet Spring eine neue Transaktion, die Ihre Testmethode und @Before/@After - Rückrufe umschließt und am Ende rückgängig macht. Es funktioniert standardmäßig, es reicht aus, einen Transaktionsmanager im Kontext zu haben.

Von: 10.3.5.4 Transaktionsverwaltung (fett gedruckt):

Im TestContext-Framework werden Transaktionen vom TransactionalTestExecutionListener verwaltet. Beachten Sie, dass TransactionalTestExecutionListener standardmäßig konfiguriert ist , auch wenn Sie in Ihrer Testklasse nicht explizit @TestExecutionListeners Deklarieren. Um die Unterstützung für Transaktionen zu aktivieren, müssen Sie jedoch eine PlatformTransactionManager - Bean im Anwendungskontext bereitstellen, die durch die Semantik @ContextConfiguration Geladen wird. Außerdem müssen Sie @Transactional Für Ihre Tests entweder auf Klassen- oder auf Methodenebene deklarieren .

110

Beiseite: Versuch, die Antwort von Tomasz Nurkiewicz zu ändern, wurde abgelehnt:

Durch diese Bearbeitung wird der Beitrag nicht einmal ein bisschen einfacher zu lesen, leichter zu finden, genauer oder zugänglicher. Änderungen sind entweder völlig überflüssig oder beeinträchtigen aktiv die Lesbarkeit.


Richtig und dauerhaft Link zum entsprechenden Abschnitt der Dokumentation über Integrationstests.

Um die Unterstützung für Transaktionen zu aktivieren, müssen Sie eine PlatformTransactionManager Bean in der ApplicationContext konfigurieren, die über die Semantik @ContextConfiguration Geladen wird.

 @ Configuration 
 @ PropertySource ("application.properties") 
 Public class Persistence {
 @Autowired 
 Environment env; 
 
 @Bean 
 DataSource dataSource () {
 Gibt eine neue DriverManagerDataSource (
 Env.getProperty ("datasource.url"), 
 Env.getProperty zurück ("datasource.user"), 
 env.getProperty ("datasource.password") 
); 
} 
 
 @Bean 
 PlatformTransactionManager transactionManager () {
 Gibt neuen DataSourceTransactionManager (dataSource ()) zurück; 
} 
} 

Außerdem müssen Sie Spring 'Annotation @Transactional Auf Klassen- oder Methodenebene für Ihre Tests deklarieren.

 @ RunWith (SpringJUnit4ClassRunner.class) 
 @ ContextConfiguration (classes = {Persistence.class, SomeRepository.class}) 
 @ Transactional 
 Public class SomeRepositoryTest {.. .} 

Wenn Sie eine Testmethode mit @Transactional Versehen, wird der Test in einer Transaktion ausgeführt, die standardmäßig nach Abschluss des Tests automatisch zurückgesetzt wird. Wenn eine Testklasse mit @Transactional Versehen ist, wird jede Testmethode in dieser Klassenhierarchie in einer Transaktion ausgeführt.

15
user2418306

Die Antworten, die das Hinzufügen von @Transactional Erwähnen, sind korrekt, aber der Einfachheit halber könnten Sie einfach Ihre Testklasse extends AbstractTransactionalJUnit4SpringContextTests Haben.

11
matt b

Ich weiß, ich bin zu spät, um eine Antwort zu schreiben, aber in der Hoffnung, dass es jemandem helfen könnte. Außerdem habe ich gerade dieses Problem gelöst, das ich bei meinen Tests hatte. Das hatte ich in meinem Test:

Meine Testklasse

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "path-to-context" })
@Transactional
public class MyIntegrationTest 

Kontext-XML

<bean id="dataSource" class="org.Apache.commons.dbcp.BasicDataSource">
   <property name="driverClassName" value="${jdbc.driverClassName}" />
   <property name="url" value="${jdbc.url}" />
   <property name="username" value="${jdbc.username}" />
   <property name="password" value="${jdbc.password}" />
</bean>

Ich hatte immer noch das Problem, dass die Datenbank nicht automatisch bereinigt wurde.

Das Problem wurde behoben, als ich die folgende Eigenschaft zu BasicDataSource hinzufügte

<property name="defaultAutoCommit" value="false" />

Ich hoffe es hilft.

4
Atul Kumbhar

Sie müssen Ihren Test mit einem Sprint-Kontext und einem Transaktionsmanager ausführen, z.

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {"/your-applicationContext.xml"})
@TransactionConfiguration(transactionManager="txMgr")
public class StudentSystemTest {

     @Test
     public void testTransactionalService() {
         // test transactional service
     }

     @Test
     @Transactional
     public void testNonTransactionalService() {
         // test non-transactional service
     }
}

Siehe Kapitel 10. Testing der Quellenangabe für weitere Details.

0
Johan Sjöberg