मैं अपने ओएस सॉफ्टवेयर में टेस्टकंटेनर का उपयोग कर रहा हूं लेकिन मुझे लगता है कि मेरे कॉन्फ़िगरेशन में या डॉकर/टेस्टकंटेनर रनटाइम में कोई समस्या है ...

मेरे पास कुछ परीक्षण हैं और जब वे अलग हो रहे हैं, तो सब कुछ ठीक काम करता है, लेकिन जब मैं सभी परीक्षणों को चलाने की कोशिश करता हूं तो आखिरी बार किसी समस्या के कारण विफल हो जाता है जब एप्लिकेशन कंटेनर से कनेक्ट करने का प्रयास करता है ..

डिबगिंग समस्या मैंने पाया कि कंटेनर एक बंदरगाह में शुरू हुआ लेकिन एप्लिकेशन अन्य बंदरगाह में कनेक्शन का प्रयास कर रहा है, फिर अधिकांश का उपयोग अंतिम परीक्षण कक्षाओं में किया जाता है

चल रहे सभी परीक्षण:

परीक्षण विफल

असफल परीक्षणों में से एक मुझे यह लॉग दिखाता है:

असफल परीक्षण का लॉग

और कंटेनर तब शुरू हुआ जब कक्षा UserControllerTest शुरू हुई, दूसरे पोर्ट का उपयोग कर रही है, जैसे:

विंडोज़ पर डॉकटर कंटेनर पोर्ट दिखा रहा है

मेरा परीक्षण विन्यास एक अमूर्त वर्ग में आधारित है (नीचे देखें) और, जैसा कि कहा गया है, यदि कोई वर्ग चलाता है जो अकेले त्रुटियां दिखा रहा है, तो सब कुछ ठीक काम करता है।

@Testcontainers
@ActiveProfiles("test")
@ExtendWith(SpringExtension::class)
@TestMethodOrder(value = OrderAnnotation::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
abstract class AbstractTest {

    companion object {

        @Container
        private val redisContainer = GenericContainer<Nothing>("redis:6-alpine")
            .apply {
                withExposedPorts(6379)
                withCreateContainerCmdModifier { cmd -> cmd.withName("wb-test-cache") }
            }

        @Container
        private val postgresContainer = PostgreSQLContainer<Nothing>("postgres:13-alpine")
            .apply {
                withExposedPorts(5432)
                withUsername("sa_webbudget")
                withPassword("sa_webbudget")
                withDatabaseName("webbudget")
                withCreateContainerCmdModifier { cmd -> cmd.withName("wb-test-database") }
            }

        @JvmStatic
        @DynamicPropertySource
        fun dynamicPropertiesRegister(registry: DynamicPropertyRegistry) {
            registry.add("spring.datasource.url", postgresContainer::getJdbcUrl)
            registry.add("spring.redis.host", redisContainer::getHost)
            registry.add("spring.redis.port", redisContainer::getFirstMappedPort)
        }
    }
}

किसी ने ऐसा कुछ देखा है इसे हल करने का तरीका जानें?

2
Arthur 5 अगस्त 2021, 05:59

3 जवाब

सबसे बढ़िया उत्तर

कुछ शोध के बाद मुझे पता चला कि समस्या क्या है: संदर्भ।

जब वसंत पहला एमवीसी नियंत्रक परीक्षण चलाता है, तो यह सभी नियंत्रकों के लिए टॉमकैट का एक उदाहरण शुरू करता है, इसका मतलब है कि जब टेस्टकंटेनर डेटाबेस के लिए डॉकर इंस्टेंस को फिर से बनाते हैं (नए नियंत्रक परीक्षण शुरू करने के बाद) गुण (पोर्ट, यूआरएल ..) नहीं थे अद्यतन किया गया क्योंकि वसंत टॉमकैट के वर्तमान उदाहरण का पुन: उपयोग करेगा (अंतिम एमवीसी परीक्षण से)

समाधान: प्रत्येक परीक्षण वर्ग के लिए संदर्भ को गंदा के रूप में चिह्नित करें, यह वसंत को हर बार एक नया परीक्षण वर्ग शुरू होने पर संदर्भ को फिर से बना देगा और यह गुणों को सही ढंग से अपडेट करने के लिए dynamicPropertiesRegister को ट्रिगर करेगा।

मुझे बस इस एनोटेशन @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) को अपने AbstractTest में जोड़ना था

0
ouflak 31 अगस्त 2021, 07:02

आप पुन: उपयोग के लिए कंटेनर शुरू करना चाहते हैं। इसे विधियों की श्रृंखला में रखें:

.withReuse(true);
0
user3034117 9 अगस्त 2021, 03:23

दस्तावेज़ीकरण के अनुसार:

स्थिर क्षेत्रों के रूप में घोषित कंटेनरों को परीक्षण विधियों के बीच साझा किया जाएगा। किसी भी परीक्षण विधि को निष्पादित करने से पहले उन्हें केवल एक बार शुरू किया जाएगा और अंतिम परीक्षण विधि के निष्पादित होने के बाद बंद कर दिया जाएगा। इंस्टेंस फ़ील्ड के रूप में घोषित कंटेनरों को शुरू किया जाएगा और प्रत्येक परीक्षण विधि के लिए बंद कर दिया जाएगा।

तो शायद आप कंटेनरों को हर परीक्षण के लिए फिर से लॉन्च कर रहे हैं और नए पोर्ट नंबर प्राप्त कर रहे हैं?

देखें: https://www.testcontainers.org/test_framework_integration/junit_5/

हम उसी के समान एक सेटअप चलाते हैं जिसे आप पूरा करना चाहते हैं, लेकिन इसके बजाय एब्सट्रैक्ट क्लास में एक @ContextConfiguration( initializers = [ का उपयोग कर रहे हैं, जिसमें इनिशियलाइज़र की सूची है जहाँ प्रत्येक कंटेनर को कॉन्फ़िगर किया गया है और साझा ConfigurableApplicationContext में जोड़ा गया है। लेकिन आपका दृष्टिकोण बहुत आसान लगता है यदि आप इसे केवल एनोटेशन का उपयोग करके काम कर सकते हैं।

0
Erik Finnman 18 अगस्त 2021, 15:13