JUnit में src / test / resource निर्देशिका का मार्ग कैसे प्राप्त करें?


275

मुझे पता है कि मैं src / test / संसाधनों से एक फ़ाइल लोड कर सकता हूं:

getClass().getResource("somefile").getFile()

लेकिन मैं src / परीक्षण / संसाधनों का पूर्ण पथ कैसे प्राप्त कर सकते हैं निर्देशिका , यानी मैं एक फ़ाइल को लोड नहीं करना चाहता, मैं सिर्फ निर्देशिका के पथ जानना चाहते हैं?


1
जिज्ञासा से बाहर: आप क्यों जानना चाहते हैं?
fge

3
@ यदि इसे परीक्षण के तहत वस्तु के पास करने की आवश्यकता है, जो एक फाइल को लोड करने के लिए इसका उपयोग करता है
रोरी

5
आपके संसाधन निर्देशिका में सीधे फ़ाइल का उपयोग एक बुरा विचार है। स्टीम पर काम करने के लिए अपने कोड को रिफलेक्टर करें, या अपने टेस्ट को पहले किसी टेम्परोग्राफी फ़ोल्डर में कॉपी बनाएं।
ओलिवर चार्ल्सवर्थ

4
@ ऑलिवरचर्ल्सवर्थ मैं टेम्प फोल्डर के बारे में सहमत हूं और org.junit.rules.TemporaryFolderहर समय उपयोग करता हूं ... लेकिन ... परीक्षण / संसाधनों से कॉपी करने के लिए आपको इसकी आवश्यकता है, एर, इसकी राह!
माइक कृंतक

1
@mikerodent - मुझे क्या लगता है कि इसका मतलब था: एक इनपुटस्ट्रीम के माध्यम से संसाधन पढ़ें, और फिर इसे एक अस्थायी फ़ाइल में लिखें।
ओलिवर चार्ल्सवर्थ

जवाबों:


204

ClassLoaderकक्षा के साथ काम करने की कोशिश करें :

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("somefile").getFile());
System.out.println(file.getAbsolutePath());

A ClassLoaderकक्षाओं में लोड करने के लिए जिम्मेदार है। हर वर्ग के लिए एक संदर्भ है ClassLoader। यह कोड Fileसंसाधन निर्देशिका से लौटता है । इस पर कॉल getAbsolutePath()करना इसकी पूर्णता देता है Path

Javadoc for ClassLoader: http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html


34
यह जरूरी एक अच्छा विचार नहीं है। यदि संसाधन एक जार में है, तो यह दुखी समय को जन्म देगा।
ओलिवर चार्ल्सवर्थ

1
@OliverCharlesworth तो, जार के मामले में क्या किया जा सकता है?
अनमोल सिंह जग्गी

@AnmolSinghJaggi - मूल प्रश्न के नीचे मेरी टिप्पणी देखें :)
ऑलिवर चार्ल्सवर्थ

जब मैं इस समाधान का उपयोग करता हूँ तो maven बिल्ड विफल हो जाता है
Firstpostcommenter

यह फ़ाइल नाम के साथ भी होगा
qwert_ukg

299

आपको क्लास लोडर के साथ गड़बड़ करने की जरूरत नहीं है। वास्तव में यह एक बुरी आदत है क्योंकि क्लास लोडर संसाधन java.io नहीं हैं। जब वे एक जार संग्रह में होते हैं, तो ऑब्जेक्ट्स।

परीक्षण चलाने से पहले मावेन स्वचालित रूप से वर्तमान कामकाजी निर्देशिका को सेट करता है, इसलिए आप बस उपयोग कर सकते हैं:

    File resourcesDirectory = new File("src/test/resources");

resourcesDirectory.getAbsolutePath() अगर आपको वास्तव में जरूरत है तो सही मूल्य लौटाएगा।

मैं एक src/test/dataनिर्देशिका बनाने की सलाह देता हूं यदि आप चाहते हैं कि आपके परीक्षण फ़ाइल सिस्टम के माध्यम से डेटा तक पहुंच सकें। यह स्पष्ट करता है कि आप क्या कर रहे हैं।


4
नई फ़ाइल ("src / परीक्षण / संसाधन / fileXYZ"); काम नहीं करेगा। न तो एक्लिप्स से और न ही मावेन से अगर आप बस इसे एक ज्यूनिट टेस्ट में डालते हैं।
seba.wagner

11
यह मावेन से ठीक काम करता है। ग्रहण में आपको परीक्षण धावक में वर्तमान कामकाजी निर्देशिका को सेट करना होगा, लेकिन कमांड लाइन मावेन आपके लिए ऐसा करता है।
स्टीव सी

4
मुझे ऐसा नहीं लगता। और आप ऐसा क्यों करेंगे, अगर आप बस एक "नई फाइल (getClass ()। GetClassLoader ()। GetResource (" fileNameXYZ.xml ")" बिना किसी भी चीज़ को सेट करने की आवश्यकता के बिना कर सकते हैं। न तो ग्रहण में और न ही मावेन में
seba। " .wagner

10
बल्कि, आप अपनी निर्माण उपयोगिता के मानकों का पालन क्यों नहीं करेंगे? खासकर जब यह आपके कोड को सरल करता है। IntelliJ या Maven का उपयोग करके, कार्यशील निर्देशिका को सेट करने की कोई आवश्यकता नहीं है। यह स्पष्ट रूप से सबसे सरल उपाय है, क्योंकि ग्रहण हमेशा की तरह एक दर्द है।
जेम्स वाटकिंस

2
IntelliJ 2014 संस्करण के लिए, मुझे अभी भी परीक्षण विधि / वर्ग के रन / डिबग कॉन्फ़िगरेशन में कार्य निर्देशिका को बदलना पड़ा, जैसा कि @Steve C ने उल्लेख किया है।
a_secenthir

76

मैं बस Pathजावा 7 से उपयोग करूंगा

Path resourceDirectory = Paths.get("src","test","resources");

साफ़ सुथरा!


क्या यह ठीक उसी कोड को विंडोज पर काम करेगा? JavaDoc Paths.get(...)सुझाव के लिए (वैसे भी मुझे) कि यह नहीं होगा।
स्टीव सी

@SteveC आप File.separatorएक पथ के रूप में उपयोग किए जाने वाले स्ट्रिंग का निर्माण करने के लिए निरंतर उपयोग कर सकते हैं
जीनलजेन

1
मुझे पता है कि, लेकिन यह बहुत बदसूरत है। इसके विपरीत, new File("src/test/resources")सभी प्लेटफार्मों पर सही काम करता है।
स्टीव सी

2
सिर्फ उपयोग क्यों नहीं Path resourceDirectory = Paths.get("src","test","resources");?
नवनीत

1
हम्म, Paths.get("src", "test", "resources")और Paths.get("src/test/resources")मेरे लिए विंडोज 10 पर ठीक काम करते हैं। मैं क्या गलत कर रहा हूं? =)
naXa

24

यदि यह एक स्प्रिंग प्रोजेक्ट है, तो हम src / test / संसाधन फ़ोल्डर से फ़ाइलें प्राप्त करने के लिए नीचे दिए गए कोड का उपयोग कर सकते हैं ।

File file = ResourceUtils.getFile(this.getClass().getResource("/some_file.txt"));

14

मेरे पास JUnit 4.12 और Java8 का उपयोग करके Maven3 प्रोजेक्ट है। के myxml.xmlतहत बुलाया एक फ़ाइल का रास्ता पाने के लिए src/test/resources, मैं परीक्षण मामले के भीतर से ऐसा करता हूं:

@Test
public void testApp()
{
    File inputXmlFile = new File(this.getClass().getResource("/myxml.xml").getFile());
    System.out.println(inputXmlFile.getAbsolutePath());
    ...
}

IntelliJ IDE के साथ Ubuntu 14.04 पर परीक्षण किया गया। संदर्भ यहाँ


11

सभी सामग्री फ़ोल्डर src/test/resourcesमें कॉपी की गई है target/test-classes। तो मावेन बिल्ड के दौरान परीक्षण संसाधनों से फ़ाइल प्राप्त करने के लिए आपको इसे test-classesफ़ोल्डर से लोड करना होगा , जैसे:

Paths.get(
    getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
).resolve(
    Paths.get("somefile")
).toFile()

विभाजन:

  1. getClass().getProtectionDomain().getCodeSource().getLocation().toURI()- आपको यूआरआई देंगे target/test-classes
  2. resolve(Paths.get("somefile"))- फोल्डर someFileको हल करता है target/test-classes

मूल anwser से लिया जाता है इस


8

@ सीटेव सी और @ एशोसबॉर्न 1 द्वारा प्रस्तावित विकल्पों में अंतर और बाधाएं हैं। मुझे निर्दिष्ट करना चाहिए, मेरा मानना ​​है।

हम कब उपयोग कर सकते हैं File resourcesDirectory = new File("src/test/resources");:?

  • 1 जब परीक्षण केवल मावेन के माध्यम से नहीं बल्कि आईडीई के माध्यम से चलाए जाने वाले हैं।
  • 2.1 जब परीक्षण मावेन या के माध्यम से चलाए जा रहे हैं
  • 2.2 आईडीई के माध्यम से और केवल एक परियोजना आईडीई में आयात की जाती है। (मैं "आयातित" शब्द का उपयोग करता हूं, क्योंकि यह IntelliJ IDEA में उपयोग किया जाता है। मुझे लगता है कि ग्रहण के उपयोगकर्ता भी अपने मावेन प्रोजेक्ट को आयात करते हैं)। यह तब काम करेगा, जब आप IDE के माध्यम से परीक्षण चलाते हैं, जो आपकी परियोजना के समान है।
  • 3.1 जब परीक्षण मावेन या के माध्यम से चलाए जा रहे हैं
  • 3.2 आईडीई के माध्यम से, और एक से अधिक परियोजनाएं आईडीई में आयात की जाती हैं (जब आप एक छात्र नहीं होते हैं, तो आप आमतौर पर कई परियोजनाओं को आयात करते हैं), और आईडीई के माध्यम से परीक्षण चलाने से पहले, आप मैन्युअल रूप से अपने परीक्षणों के लिए कार्य निर्देशिका को कॉन्फ़िगर करते हैं। उस कार्यशील निर्देशिका को आपके आयातित प्रोजेक्ट का उल्लेख करना चाहिए जिसमें परीक्षण शामिल हैं। डिफ़ॉल्ट रूप से, आईडीई में आयातित सभी परियोजनाओं की कार्यशील निर्देशिका केवल एक है। संभवतः यह IntelliJ IDEAकेवल एक प्रतिबंध है , लेकिन मुझे लगता है कि सभी आईडीई इस तरह से काम करते हैं। और यह कॉन्फ़िगरेशन जो मैन्युअल रूप से किया जाना चाहिए, बिल्कुल अच्छा नहीं है। विभिन्न मावेन परियोजनाओं में मौजूद कई परीक्षणों के साथ काम करना, लेकिन एक बड़ी "आईडीई" परियोजना में आयात किया गया, हमें यह याद रखने के लिए मजबूर करें और अपने काम से आराम करने और खुशी प्राप्त करने की अनुमति न दें।

@ Ashosborne1 (व्यक्तिगत रूप से मैं इसे पसंद करता हूं) द्वारा पेश किए गए समाधान के लिए 2 अतिरिक्त आवश्यकताओं की आवश्यकता होती है जो आपको परीक्षण चलाने से पहले करना चाहिए। इस समाधान का उपयोग करने के लिए चरणों की एक सूची इस प्रकार है:

  • "Src / परीक्षण / संसाधन /" के अंदर एक परीक्षण फ़ोल्डर ("टेवा") और फ़ाइल ("रीडमी") बनाएँ:

    src / परीक्षण / संसाधन / टेवा / रीडमी

    फ़ाइल को परीक्षण फ़ोल्डर में बनाया जाना चाहिए, अन्यथा, यह काम नहीं करेगा। मावेन खाली फ़ोल्डरों की अनदेखी करता है।

  • कम से कम एक बार के माध्यम से परियोजना का निर्माण mvn clean install। यह परीक्षण भी चलाएगा। यह एक पूरी परियोजना के निर्माण के बिना मावेन के माध्यम से केवल अपने परीक्षण वर्ग / विधि को चलाने के लिए पर्याप्त हो सकता है। परिणामस्वरूप आपके परीक्षण संसाधनों को परीक्षण-कक्षाओं में कॉपी किया जाएगा, यहाँ एक रास्ता है:target/test-classes/teva/readme

  • उसके बाद, आप कोड का उपयोग करके फ़ोल्डर तक पहुंच सकते हैं, पहले से ही @ ashosborne1 द्वारा ऑफ़र किया गया (मुझे क्षमा करें, मैं इस कोड को आइटम की इस सूची के अंदर सही तरीके से संपादित नहीं कर सका):

public static final String TEVA_FOLDER = "teva"; ... 
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

अब आप अपना परीक्षण IDE के माध्यम से जितनी बार चाहें, चला सकते हैं। जब तक आप मावेन को साफ न चलाएं। यह लक्ष्य फ़ोल्डर को छोड़ देगा।

एक परीक्षण फ़ोल्डर के अंदर फ़ाइल बनाना और पहली बार मावेन चलाना, इससे पहले कि आप आईडीई के माध्यम से परीक्षण चलाएं आवश्यक कदम हैं। इन चरणों के बिना, यदि आप सिर्फ अपने आईडीई में परीक्षण संसाधन बनाते हैं, तो परीक्षण लिखें और इसे केवल आईडीई के माध्यम से चलाएं, आपको एक त्रुटि मिलेगी। एमवीएन के माध्यम से परीक्षण चलाने से परीक्षण संसाधनों को लक्ष्य / परीक्षण-कक्षाओं / टेवा / रीडमे में बदल दिया जाता है और वे एक क्लास लोडर के लिए सुलभ हो जाते हैं।

आप पूछ सकते हैं, मुझे आईडीई में एक से अधिक मावेन परियोजना के आयात की आवश्यकता क्यों है और इतनी जटिल चीजें क्यों हैं? मेरे लिए, मुख्य प्रेरणा में से एक: आईडीए से संबंधित फाइलों को कोड से दूर रखना। मैं पहली बार अपनी IDE में एक नया प्रोजेक्ट बनाता हूं। यह एक फर्जी प्रोजेक्ट है, जो आईडीई से संबंधित फाइलों का धारक है। फिर, मैं पहले से मौजूद मावेन परियोजनाओं का आयात करता हूं। मैं इन आयातित परियोजनाओं को केवल अपनी मूल नकली परियोजना में IDEA फाइलें रखने के लिए मजबूर करता हूं। परिणामस्वरूप मुझे कोड के बीच आईडीई-संबंधित फाइलें दिखाई नहीं देती हैं। SVN को उन्हें नहीं देखना चाहिए (कृपया ऐसी फ़ाइलों को अनदेखा करने के लिए svn / git को कॉन्फ़िगर करने की पेशकश न करें, कृपया)। इसके अलावा यह बहुत सुविधाजनक है।


हाय एलेक्जेंड्रा, मैं लक्ष्य / वर्गों और src / main / संसाधन में संसाधन फ़ाइल के साथ परेशानी में हूँ और आपको इसके बारे में केवल एक ही बात लगती है। पहले मेरे पास src / main / resource पर फाइलें हैं, प्रोजेक्ट बनाने के बाद, यह इन फाइलों को लक्ष्य / कक्षाओं में कॉपी करता है। और इससे, getClass ()। GetClassLoader ()। GetResource (fileName) केवल लक्ष्य फ़ोल्डर पर काम करता है जबकि मैं चाहता हूँ कि मैं src / main पर काम करूँ। क्या आप मुझे लिंक दे सकते हैं कहीं getResource फ़ाइल के तंत्र के बारे में बताएं? संसाधन फ़ोल्डर को कैसे कॉन्फ़िगर करें? Tks: D
Huy Hóm H

2
@ ह्युम होन, मैं यह नहीं करने की सलाह दूंगा। मुझे डर है कि आप गलत दिशा में जा रहे हैं। ऐसी कुछ जगहें हैं जहाँ संसाधन फ़ाइलें स्थित हैं, वे स्थान अन्य सभी के लिए जाने जाते हैं। ऐसी परियोजनाओं को बनाए रखना आसान है। यहां तक ​​कि आपके लिए यह आसान होगा, आपको सिर्फ मावेन परियोजनाओं की संरचना को समझने की आवश्यकता है। लेकिन सुनिश्चित करने के लिए, आप [ maven.apache.org/plugins/maven-resources-plugin/examples/…
एलेक्जेंडर

@ HuyHómHỉnh, इसके समाधान पर भी एक नज़र डालें: stackoverflow.com/questions/23289098/… लेकिन आपको संसाधन के रूप में src / main को कॉन्फ़िगर करने के लिए ... इससे बचने की कोशिश करें, ऐसा लगता है कि आप कुछ गलत कर रहे हैं।
एलेक्जेंडर

एचएम। क्या आप बता सकते हैं कि इसमें क्या गलत है .gitignore? यह भी लगता है कि जब परीक्षण चल रहा हो तो आईडीईए स्वचालित रूप से मावेन चलाता है (और डिफ़ॉल्ट रूप से सही काम करने की हिम्मत सेट करता है $MODULE_DIR$)। तो mvn testइससे पहले मैन्युअल रूप से चलाने की आवश्यकता नहीं है, सब कुछ मावेन और आईडीईए से ठीक काम करता है "src/test/resources/somefile.txt"
एलेक्स पी।

5

मेरे द्वारा उपयोग किया जाने वाला सबसे सरल और साफ समाधान, मान लीजिए कि परीक्षण वर्ग का नाम है TestQuery1और resourcesआपके testफ़ोल्डर में एक निर्देशिका इस प्रकार है:

├── java
   └── TestQuery1.java
└── resources
    └── TestQuery1
        ├── query.json
        └── query.rq

करने के लिए URI प्राप्त TestQuery1करें:

URL currentTestResourceFolder = getClass().getResource("/"+getClass().getSimpleName());

किसी एक फ़ाइल का URI प्राप्त करने के लिए TestQuery1:

File exampleDir = new File(currentTestResourceFolder.toURI());
URI queryJSONFileURI = exampleDir.toURI().resolve("query.json");

1
कोई चिंता नहीं, वास्तव में आपकी मदद के लिए धन्यवाद !! अच्छी बात यह है कि आपके उत्तर को हटाकर, मैं प्रश्न को हटाने में सक्षम हूं। हाँ, यहाँ भी काफी निराश हैं, लेकिन वैसे भी धन्यवाद !! शुभ संध्या :)
नूर

1

आप किसी सामान्य मामले में परीक्षण के लिए संसाधन फ़ोल्डर से फ़ाइल का उपयोग नहीं कर सकते। कारण यह है कि संसाधन फ़ोल्डर में संसाधन फ़ाइलों को एक जार के अंदर संग्रहीत किया जाता है। इसलिए उनके पास फ़ाइल सिस्टम में एक वास्तविक रास्ता नहीं है।

सबसे सरल समाधान हो सकता है:

  1. अस्थायी फ़ोल्डर में संसाधनों से फ़ाइल कॉपी करें और उस अस्थायी फ़ाइल का पथ प्राप्त करें।
  2. अस्थायी पथ का उपयोग करके परीक्षण करें।
  3. अस्थायी फ़ाइल हटाएँ।

TemporaryFolderसे JUnitअस्थायी फ़ाइलों को बनाने और परीक्षण की शिकायत होने के बाद इसे हटाने के लिए इस्तेमाल किया जा सकता है। guavaलाइब्रेरी से कक्षाएं एक फाइल फॉर्म संसाधन फ़ोल्डर की प्रतिलिपि बनाने के लिए उपयोग की जाती हैं।

कृपया, ध्यान दें कि यदि हम संसाधन फ़ोल्डर में एक सबफ़ोल्डर का उपयोग goodकरते हैं, तो एक की तरह , हमें /संसाधन पथ में अग्रणी नहीं जोड़ना पड़ेगा ।

public class SomeTest {

    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();


    @Test
    public void doSomethinge() throws IOException {
        File file = createTmpFileFromResource(tmpFolder, "file.txt");
        File goodFile = createTmpFileFromResource(tmpFolder, "good/file.txt");

        // do testing here
    }

    private static File createTmpFileFromResource(TemporaryFolder folder,
                                                  String classLoaderResource) throws IOException {
        URL resource = Resources.getResource(classLoaderResource);

        File tmpFile = folder.newFile();
        Resources.asByteSource(resource).copyTo(Files.asByteSink(tmpFile));
        return tmpFile;
    }

}

0

अपने यूनिट परीक्षणों में स्प्रिंग के साथ हाइबरनेट इंजेक्ट करने के लिए निम्नलिखित का उपयोग करें:

@Bean
public LocalSessionFactoryBean getLocalSessionFactoryBean() {
    LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
    localSessionFactoryBean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
    localSessionFactoryBean.setPackagesToScan("com.example.yourpackage.model");
    return localSessionFactoryBean;
}

यदि आपके पास hibernate.cfg.xmlअपने src/test/resourcesफ़ोल्डर में मौजूद नहीं है तो यह स्वचालित रूप से आपके src/main/resourcesफ़ोल्डर में वापस आ जाएगा ।


0

अपनी फ़ाइल ऑब्जेक्ट पर .getAbsolutePath () का उपयोग करें।

getClass().getResource("somefile").getFile().getAbsolutePath()

getFile रिटर्न स्ट्रिंग इंस्टेंस नहीं FIle
अल्मास अब्द्राजक

@AlmasAbdrazak GreatDantone यह नहीं कहता कि getFile()फ़ाइल का एक उदाहरण देता है। वह कहता है कि getAbsolutePath()फ़ाइल ऑब्जेक्ट के उदाहरण पर उपयोग किया जाता है।
menteith

@menteith अपने कोड के अनुसार, वह getFile () और उसके बाद getAbsolutePath () getFile () पर कॉल करता है, लेकिन getFile () String देता है और आप getAbsolutePath () को स्ट्रिंग ऑब्जेक्ट
Almas Abdrazak

0

वसंत के साथ आप इसे आसानी से संसाधन फ़ोल्डर से पढ़ सकते हैं (या तो मुख्य / संसाधन या परीक्षण / संसाधन):

उदाहरण के लिए एक फ़ाइल बनाएँ: test/resources/subfolder/sample.json

@Test
public void testReadFile() {
    String json = this.readFile("classpath:subfolder/sample.json");
    System.out.println(json);
}

public String readFile(String path) {
    try {
        File file = ResourceUtils.getFile(path);
        return new String(Files.readAllBytes(file.toPath()));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

0
List<String> lines = Files.readAllLines(Paths.get("src/test/resources/foo.txt"));
lines.forEach(System.out::println);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.