Po pierwsze, znalazłem wiele wątków na ten temat w StackOverflow, ale żaden z nich tak naprawdę mi nie pomógł, więc przepraszam, że zadaję prawdopodobnie zduplikowane pytanie.
Przeprowadzam testy JUnit za pomocą testu sprężynowego, mój kod wygląda następująco
@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() {
}
...
}
Mój problem polega na tym, że chcę, aby moje testy NIE wpływały na inne testy. Chciałbym więc stworzyć coś takiego jak wycofywanie zmian dla każdego testu. Szukałem dużo tego, ale jak dotąd nic nie znalazłem. Używam do tego Hibernate i MySql
initTest
Odpowiedzi:
Po prostu dodaj
@Transactional
adnotację na górze testu:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"testContext.xml"}) @Transactional public class StudentSystemTest {
Domyślnie Spring rozpocznie nową transakcję otaczającą twoją metodę testową i
@Before
/@After
callbacki, wycofując na koniec. Domyślnie działa, wystarczy mieć w kontekście jakiegoś menedżera transakcji.Od: 10.3.5.4 Zarządzanie transakcjami (moje pogrubienie):
źródło
PlatformTransactionManager
. W przeciwnym razie skąd Spring będzie wiedzieć o Twoich transakcjach i bazie danych?@Transactional
na@Test
poziomie metody, a nie na poziomie klasy.Na boku: odrzucono próbę zmiany odpowiedzi Tomasza Nurkiewicza:
Prawidłowy i stały link do odpowiedniej sekcji dokumentacji dotyczącej testów integracyjnych.
źródło
Odpowiedzi dotyczące dodawania
@Transactional
są poprawne, ale dla uproszczenia możesz po prostu mieć swoją klasę testowąextends AbstractTransactionalJUnit4SpringContextTests
.źródło
Wiem, jestem za późno, aby opublikować odpowiedź, ale mam nadzieję, że może to komuś pomóc. Poza tym właśnie rozwiązałem ten problem, który miałem z moimi testami. Oto, co miałem w moim teście:
Moja klasa testowa
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "path-to-context" }) @Transactional public class MyIntegrationTest
Context 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>
Nadal miałem problem, że baza danych nie była czyszczona automatycznie.
Problem został rozwiązany, gdy dodałem następującą właściwość do BasicDataSource
<property name="defaultAutoCommit" value="false" />
Mam nadzieję, że to pomoże.
źródło
Musisz uruchomić swój test z kontekstem Springa i menedżerem transakcji, np.
@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 } }
Więcej informacji można znaleźć w rozdziale
3.5.8. Transaction Management
Źródła wiosenne.źródło
Oprócz dodawania
@Transactional
na@Test
metody, trzeba także dodać@Rollback(false)
źródło
Możesz wyłączyć wycofywanie zmian:
@TransactionConfiguration(defaultRollback = false)
Przykład:
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @Transactional @TransactionConfiguration(defaultRollback = false) public class Test { @PersistenceContext private EntityManager em; @org.junit.Test public void menge() { PersistentObject object = new PersistentObject(); em.persist(object); em.flush(); } }
źródło