2012-05-09 3 views
18

Se ho una classe con un metodo @PostConstruct, come posso testare il suo costruttore e quindi il suo metodo @PostConstruct usando JUnit e Spring? Non posso semplicemente usare il nuovo ClassName (param, param) perché non usa Spring - il metodo @PostConstruct non viene licenziato.Come testare il costruttore di una classe che ha un metodo @PostConstruct che usa Spring?

Mi manca qualcosa di ovvio qui?

public class Connection { 

private String x1; 
private String x2; 

public Connection(String x1, String x2) { 
this.x1 = x1; 
this.x2 = x2; 
} 

@PostConstruct 
public void init() { 
x1 = "arf arf arf" 
} 

} 


@Test 
public void test() { 
Connection c = new Connection("dog", "ruff"); 
assertEquals("arf arf arf", c.getX1(); 
} 

ho qualcosa di simile (anche se un po 'più complessa) di questo e il metodo @PostConstruct non viene colpito.

risposta

11

Dai un'occhiata allo Spring JUnit Runner.

È necessario inserire la classe nella classe di test in modo che spring costruisca la classe e invochi anche il metodo di post-costruzione. Fai riferimento all'esempio clinico dell'animale domestico.

esempio:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:your-test-context-xml.xml") 
public class SpringJunitTests { 

    @Autowired 
    private Connection c; 

    @Test 
    public void tests() { 
     assertEquals("arf arf arf", c.getX1(); 
    } 

    // ... 
+0

Lo capisco, come ho affermato. Ma come posso testare più permutazioni di questo costruttore all'interno di una classe di test? Cosa non sto dicendo chiaramente sulla mia domanda? – AHungerArtist

+0

Voglio cinque casi di test per il costruttore di questa classe. Non c'è davvero modo migliore di avere un contesto app con cinque di questi bean e caricarlo? – AHungerArtist

+0

In tempo reale se ci sono 5 possibili modi per iniettare la tua classe, allora temo di dover creare 5 definizioni di bean in quel caso. –

0

@PostConstruct deve modificare lo stato dell'oggetto. Quindi, nel caso di test di JUnit, dopo aver ottenuto il bean, controlla lo stato dell'oggetto. Se è uguale allo stato impostato da @PostConstruct, il test ha esito positivo.

+0

Il problema non è come testare che è cambiato, ma che @PostConstruct non viene licenziato. Modificherò il mio post per renderlo più chiaro. – AHungerArtist

0

Per impostazione predefinita, Primavera non sarà a conoscenza del @PostConstruct e @PreDestroy annotazione. Per abilitarlo, devi registrare "CommonAnnotationBeanPostProcessor" o specificare "" nel file di configurazione del bean.

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />

o

<context:annotation-config />

17

Se l'unico container gestito parte della Connection è il tuo metodo @PostContruct, basta chiamare manualmente in un metodo di prova:

@Test 
public void test() { 
    Connection c = new Connection("dog", "ruff"); 
    c.init(); 
    assertEquals("arf arf arf", c.getX1()); 
} 

Se c'è è più di questo, come le dipendenze e così via si può ancora iniettare manualmente o, come dichiarato da Sridhar, utilizzare un quadro di prova a molla.

+0

Questo è quello che ho finito per fare. – AHungerArtist

+7

init può essere privato –

+0

@shanyangqu Quindi è possibile utilizzare ReflectionTestUtils o equivalente, ad esempio. È un codice di prova dopotutto. – mrembisz