junit molla carica il contesto dell’applicazione per i test

Ho alcuni file XML sotto la mia directory WEB-INF:

  • lyricsBaseApp-servlet.xml
  • hibernate.xml
  • dataSource.xml
  • beans.xml

il servlet xml importa altri file xml:

   

Vorrei che la mia class junit4 JukeboxTest includesse l’intera configurazione a molla. Usando il nome file predefinito ho creato un file JukeboxTest-content.xml . E infine, non so cosa mettere lì …

Ho provato:

    

o

    

e alcune altre idee, ma tutte fallirono. Qualcuno potrebbe indicarmi come accedere a quei file e in che modo Spring interpreta quei percorsi di file?

Opzione 1 (dovrebbe essere preferita in quanto è la migliore pratica):
Riforma i tuoi file di configurazione sotto WEB-INF e sposta le parti comuni (che vuoi accedere anche dai test di integrazione) a src/main/resources/ . Quindi scrivi i file di configurazione specifici del test in src/test/resources/ (se hai solo bisogno di importare diversi file di configurazione da src/main per assemblare il tuo contesto di test, salta questo e usa preferibilmente @ContextConfiguration ).

Opzione 2 (mod):
Usa riferimenti come:

 @ContextConfiguration("file:src/main/webapp/WEB-INF/dataSource.xml") 

Opzione 3 (hack):
Se si dispone di un progetto Maven, è ansible configurare il maven-surefire-plugin (utilizzato nella fase di test) per dichiarare src/main/webapp come un elemento classpath aggiuntivo durante l’esecuzione del test.

Le ultime due opzioni sono considerate come hack, perché i file sotto src/main/webapp semplicemente non dovrebbero trovarsi sul classpath.

Ora la spiegazione dettagliata:

Il motivo per cui non è ansible fare riferimento a questi file come classpath:/WEB-INF/*.xml è che non si trovano effettivamente sul classpath. È importante capire come viene confezionata la tua webapp e cosa finisce esattamente nel classpath. Supponendo una struttura di progetto Maven predefinita:

  1. Le classi Java da src/main/java vanno a /WEB-INF/classs dopo la compilazione.
  2. Anche le risorse da src/main/resources vanno a /WEB-INF/classs .
  3. Le dipendenze del progetto vanno a /WEB-INF/lib .
  4. Tutto ciò che hai in src/main/webapp va a / (root del pacchetto). Ciò significa che tutti i file da src/main/webapp/WEB-INF vanno a /WEB-INF , ovviamente.

La cosa più importante da sapere è che il classpath conterrà solo /WEB-INF/classs e una voce per ogni jar in /WEB-INF/lib . Di conseguenza, le risorse al di fuori di queste due posizioni sono completamente invisibili per il classloader. Questo vale anche per i file di configurazione xml direttamente in /WEB-INF , motivo per cui il classpath:/WEB-INF/dataSource.xml riferimento classpath:/WEB-INF/dataSource.xml non funzionerà mai.

Potresti chiederti, come diavolo sono questi file di configurazione xml caricati da Spring se non sono raggiungibili dal classpath? La risposta è semplice: quando avvii la tua webapp (al contrario dell’esecuzione di solo test di unità / integrazione), è in esecuzione in un contenitore servlet che fornisce l’accesso al ServletContext (una class effettiva dall’API Servlet), quindi utilizza ServletContext.getResourceAsStream() per caricare questi file. La chiave per la comprensione è la seguente citazione dal javadoc di questo metodo:

Questo metodo è diverso da java.lang.Class.getResourceAsStream, che utilizza un programma di caricamento classi. Questo metodo consente ai contenitori servlet di rendere disponibile una risorsa per un servlet da qualsiasi posizione, senza utilizzare un programma di caricamento classi.

Spiacente, questo è troppo lungo, ma questa è l’intera storia …

prova questo

 @ContextConfiguration(locations = {"classpath:**/dataSource.xml", "classpath:**/hibernate.xml", "classpath:**/WEB-INF/beans.xml"})