2011-10-11 1 views
5

Situazione: Ho una classe di implementazione del servizio annotata con @Service con accesso al file delle proprietà.Come accedere all'oggetto Spring @Service da jUnit test

@Service("myService") 
public class MySystemServiceImpl implements SystemService{ 

     @Resource 
     private Properties appProperties; 

} 

L'oggetto proprietà è configurato tramite file di configurazione. applicationContext.xml

<util:properties id="appProperties" location="classpath:application.properties"/> 

voglio provare alcuni metodi di questa implementazione.

Domanda: Come accedere all'oggetto MySystemServiceImpl dalla classe di test in modo che l'applicazione ProprietàProprietà venga inizializzata correttamente?

public class MySystemServiceImplTest { 

    //HOW TO INITIALIZE PROPERLY THROUGH SPRING? 
    MySystemServiceImpl testSubject; 

    @Test 
    public void methodToTest(){ 
     Assert.assertNotNull(testSubject.methodToTest()); 
    }  

} 

non posso semplice creare nuove MySystemServiceImpl - rispetto ai metodi che utilizzano AppProperties getta NullPointerException. E non posso iniettare direttamente le proprietà nell'oggetto - non esiste un metodo setter appropriato.

Basta mettere passaggi corretti qui (grazie a @NimChimpsky per risposta):

  1. ho copiato application.properties in prova/risorse dir.

  2. Ho copiato applicationContext.xml in test/risorse dir. Nel contesto di applicazione aggiungo nuovo bean (definizione delle proprietà dell'applicazione è già qui):

    <bean id="testSubject" class="com.package.MySystemServiceImpl"> 
    
  3. ho modificato classe di test in modo tale:

    @RunWith(SpringJUnit4ClassRunner.class) 
    @ContextConfiguration(locations={"/applicationContext.xml"}) 
    public class MySystemServiceImplTest { 
    
        @Autowired 
        MySystemServiceImpl testSubject; 
    
    } 
    
  4. E questo rende il trucco - adesso nel mio classe di test oggetto completamente funzionale è disponibile

risposta

7

In alternativa, per eseguire un test di integrazione, lo faccio.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"/applicationContext-test.xml"}) 
@Transactional 
public class MyTest { 

    @Resource(name="myService") 
    public IMyService myService; 

Quindi utilizzare il servizio come si farebbe normalmente. Aggiungi il contesto dell'app alla directory test/risorse

+0

Grazie, aiuta molto. – dim1902

1

Basta usare il suo costruttore:

MySystemServiceImpl testSubject = new MySystemServiceImpl(); 

Questo è un test di unità. Un test unitario verifica una classe isolata dalle altre classi e dall'infrastruttura.

Se la tua classe ha dipendenze su altre interfacce, prendi in giro queste interfacce e crea l'oggetto con questi mock come argomento. Questo è il punto principale dell'iniezione di dipendenza: essere in grado di iniettare altre, finte implementazioni all'interno di un oggetto per testare facilmente questo oggetto.

EDIT:

Si dovrebbe fornire un setter per le proprietà oggetto, al fine di essere in grado di iniettare le proprietà desiderate per ciascuno dei test di unità. Le proprietà iniettate potrebbero contenere valori nominali, valori estremi o valori errati a seconda di ciò che si desidera testare. L'iniezione sul campo è pratica, ma non si adatta bene ai test unitari. Quando si utilizza il test unitario, è preferibile l'iniezione del costruttore o del setter, perché l'obiettivo principale dell'iniezione di dipendenza è proprio quello di essere in grado di iniettare simulazioni o specifiche dipendenze nei test unitari.

+0

Purtroppo non ho la possibilità di modificare la classe. Questo è il motivo per cui devo attenermi all'iniezione di primavera. In tutto il resto sono d'accordo con il tuo punto di vista – dim1902