@Test के बाद रोलबैक लेनदेन


85

सबसे पहले, मैंने इस बारे में स्टैकऑवरफ्लो पर बहुत सारे सूत्र पाए हैं, लेकिन उनमें से किसी ने वास्तव में मेरी मदद नहीं की, इसलिए संभवतः डुप्लिकेट प्रश्न पूछने के लिए क्षमा करें।

मैं स्प्रिंग-टेस्ट का उपयोग करके JUnit परीक्षण चला रहा हूं, मेरा कोड इस तरह दिखता है

@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() {
    }    
    ...  
}

मेरी समस्या यह है कि मैं चाहता हूं कि मेरे परीक्षण अन्य परीक्षणों को प्रभावित न करें। इसलिए मैं प्रत्येक टेस्ट के लिए रोलबैक जैसा कुछ बनाना चाहता हूं। मैंने इसके लिए बहुत खोज की है, लेकिन मुझे अब तक कुछ नहीं मिला है। मैं इसके लिए हाइबरनेट और MySql का उपयोग कर रहा हूं


रोलबैक से आपका क्या मतलब है? डेटाबेस की सफाई?
गौरव

5
इसे उसी राज्य में स्थापित करना जो इसे निष्पादित करने के बाद किया गया थाinitTest
जन वोरकॉक

जवाबों:


127

बस @Transactionalअपने परीक्षण के शीर्ष पर एनोटेशन जोड़ें :

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

डिफ़ॉल्ट रूप से स्प्रिंग आपके परीक्षण विधि और @Before/ @Afterकॉलबैक के आसपास एक नया लेनदेन शुरू करेगा , जो अंत में वापस आ जाएगा। यह डिफ़ॉल्ट रूप से काम करता है, यह संदर्भ में कुछ लेनदेन प्रबंधक के लिए पर्याप्त है।

से: 10.3.5.4 लेनदेन प्रबंधन (बोल्ड मेरा):

TestContext ढांचे में लेनदेन TransactionalTestExecutionListener द्वारा प्रबंधित किए जाते हैं। ध्यान दें कि डिफ़ॉल्ट रूपTransactionalTestExecutionListener से कॉन्फ़िगर किया गया है , भले ही आप स्पष्ट रूप @TestExecutionListenersसे अपने परीक्षण वर्ग पर घोषित न करें। लेन-देन के लिए समर्थन सक्षम करने के लिए, हालांकि, आपको शब्दार्थ PlatformTransactionManagerद्वारा लोड किए गए एप्लिकेशन संदर्भ में बीन प्रदान करना होगा @ContextConfiguration। इसके अलावा, आपको @Transactionalअपने परीक्षणों के लिए या तो कक्षा या विधि स्तर पर घोषित करना होगा


2
ठीक है, मैंने पहले यह कोशिश की थी, और यह अभी भी काम नहीं करता है, हो सकता है ... समस्या यह हो सकती है कि मैंने PlatformTransactionManager को परिभाषित नहीं किया, मैं यह कैसे कर सकता हूं?
Jan Vorcak

@ जावा: आप डेटाबेस को कैसे संशोधित कर रहे हैं? यदि आप Jpa / Hibernate / JdbcTemplate / ... का उपयोग कर रहे हैं, तो कुछ होना चाहिए PlatformTransactionManager। अन्यथा स्प्रिंग को आपके लेनदेन और डेटाबेस के बारे में कैसे पता चलेगा?
टॉमाज़ नर्कविक्ज़

1
इस उत्तर में लिंक अब सही नहीं है; सही लिंक और स्प्रिंग डॉक्यूमेंटेशन से अधिक संदर्भ के लिए नीचे देखें user2418306 का उत्तर
डेवेडेवडेव

1
मैं काम नहीं करता, प्रत्येक विधि को एक अलग लेनदेन की आवश्यकता होती है, यह पूरी कक्षा के लिए नहीं कर सकता है
कामिल नेकानोविच

मैं एक मेज में एक सम्मिलित परीक्षण कर रहा हूँ। @Transactional के साथ, सम्मिलित कमांड डेटाबेस के खिलाफ भी जारी नहीं किया जाता है (मैं देख सकता हूं कि कंसोल में हाइबरनेट शो-एसक्यूएल सच है)। कई मामलों में ठीक काम करता है। लेकिन मेरा एक परीक्षण यह जाँचता है कि डेटाबेस डेटाबेस बाधा के कारण डेटाबेस एक DataAccessException जारी करता है। इस मामले में परीक्षण विफल हो जाता है क्योंकि रोलबैक "मेमोरी में" होता है और डेटाबेस को कभी नहीं कहा जाता है। समाधान: विधि के स्तर @Transactionalपर उपयोग करें @Testऔर वर्ग स्तर पर नहीं।
पाउलो मर्सन

17

इसके अलावा: टॉमाज़ नर्कविक्ज़ के जवाब को संशोधित करने का प्रयास अस्वीकार कर दिया गया था:

यह संपादन पोस्ट को पढ़ने में थोड़ा आसान, खोजने में आसान, अधिक सटीक या अधिक सुलभ नहीं बनाता है। परिवर्तन या तो पूरी तरह से सतही हैं या पठनीयता को सक्रिय रूप से नुकसान पहुंचाते हैं।


एकीकरण परीक्षण के बारे में दस्तावेज़ीकरण के संबंधित अनुभाग के लिए सही और स्थायी लिंक

लेन-देन के लिए सहायता सक्षम करने के लिए, आपको PlatformTransactionManagerसेम को उसी में कॉन्फ़िगर करना होगा ApplicationContextजो @ContextConfigurationशब्दार्थ के माध्यम से भरी हुई है ।

@Configuration
@PropertySource ( "application.properties")
सार्वजनिक वर्ग की दृढ़ता {
    @Autowired
    पर्यावरण env;

    @सेम
    डेटा स्रोत डेटा स्रोत () {
        नया DriverManagerDataSource लौटें (
                env.getProperty ( "datasource.url"),
                env.getProperty ( "datasource.user"),
                env.getProperty ( "datasource.password")
        );
    }

    @सेम
    PlatformTransactionManager लेन-देन प्रबंधक () {
        नया DataSourceTransactionManager (dataSource ()) वापस करें;
    }
}

इसके अलावा, आपको @Transactionalअपने परीक्षणों के लिए या तो कक्षा या विधि के स्तर पर स्प्रिंग के एनोटेशन की घोषणा करनी चाहिए ।

@RunWith (SpringJUnit4ClassRunner.class)
@ContextConfiguration (classes = {Persistence.class, SomeRepository.class})
@Transactional
सार्वजनिक वर्ग SomeRepositoryTest {...}

परीक्षण पद्धति का उल्लेख करने से परीक्षण @Transactionalएक लेन-देन के भीतर चलता है, जो डिफ़ॉल्ट रूप से, परीक्षण के पूरा होने के बाद स्वचालित रूप से वापस आ जाएगा। यदि एक परीक्षण वर्ग के साथ एनोटेट किया जाता है @Transactional, तो उस श्रेणी पदानुक्रम के भीतर प्रत्येक परीक्षण विधि एक लेनदेन के भीतर चलाई जाएगी।


12

जोड़ने @Transactionalका उल्लेख करने वाले उत्तर सही हैं, लेकिन सादगी के लिए आप सिर्फ अपना परीक्षण वर्ग रख सकते हैं extends AbstractTransactionalJUnit4SpringContextTests


1
क्लास लेवल पर एनोटेशन '
@ ट्रान्सटेक्शनल

5

मुझे पता है, मुझे उत्तर पोस्ट करने में बहुत देर हो चुकी है, लेकिन उम्मीद है कि यह किसी की मदद कर सकता है। साथ ही, मैंने अपने परीक्षणों के साथ इस मुद्दे को हल किया। यह वही है जो मैंने अपने परीक्षण में दिया था:

मेरी परीक्षा कक्षा

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

प्रसंग 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>

मुझे अभी भी समस्या थी कि, डेटाबेस को स्वचालित रूप से साफ नहीं किया जा रहा था।

जब मैंने BasicDataSource को निम्नलिखित संपत्ति जोड़ दी तो समस्या हल हो गई

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

आशा करता हूँ की ये काम करेगा।


ठीक है, तो आप अपने बयानों को मैन्युअल रूप से करते हैं? क्या आप सुनिश्चित हैं कि आपका डेटा आपके डेटाबेस में भी लिखा गया था?
फ्रांता कोकौरेक

स्प्रिंग लेन-देन को समझने के लिए संघर्ष करने वाले किसी व्यक्ति के लिए, सुनिश्चित करें कि आपका डेटा स्रोत ऑटो-कमिट पर सेट नहीं है या आप खुद को पागल करने की कोशिश करेंगे कि यह पता लगाने की कोशिश क्यों की जा रही है कि @ ट्रेंसेक्शनल कुछ नहीं कर रहा है।
जो अर्न्स्ट

2

आपको अपना परीक्षण स्प्रिंग संदर्भ और लेन-देन प्रबंधक, जैसे,

@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
     }
}

3.5.8. Transaction Managementआगे के विवरण के लिए स्प्रिंग संदर्भ का अध्याय देखें।


0

जोड़ने के अलावा @Transactionalपर @Testविधि, आप भी जोड़ने की जरूरत@Rollback(false)


-4

आप रोलबैक को अक्षम कर सकते हैं:

@TransactionConfiguration(defaultRollback = false)

उदाहरण:

@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();
    }
}

6
यह ठीक विपरीत है जो ओपी पूछ रहा है
एडम मिशालिक

यह स्वीकृत उत्तर के लिए एक टिप्पणी होनी चाहिए थी।
डेरामाइक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.