2015-03-28 14 views
6

ho questo codice:Iniezione di bean Mockito e CDI, @InjectMocks chiama @PostConstruct?

class Patient { 

    @Inject Syringe syringe; 

    @PostConstruct 
    void sayThankyouDoc() { 

    System.out.println("That hurt like crazy!"); 

    } 

} 

@RunWith(MockitoJUnitRunner.class) 
class TestCase { 

    @Mock 
    Syringe siringeMock; 

    @InjectMocks 
    Patient patient; 

    //... 

} 

mi aspettavo Mockito chiamare PostConstruct, ma ho dovuto aggiungere:

@Before 
public void simulate_post_construct() throws Exception { 
    Method postConstruct = Patient.class.getDeclaredMethod("sayThankyouDoc", null); 
    postConstruct.setAccessible(true); 
    postConstruct.invoke(patient); 
} 

C'è un modo migliore per fare questo?

+1

un disegno diverso che sia più leggibile e più facile da testare, è quello di non usare '@ PostConstruct' a tutti, e utilizzare l'iniezione del costruttore, invece di iniezione campo – geoand

+0

@geoand ma che cosa è l'iniezione del costruttore? – gurghet

+0

Vedere la mia risposta sotto – geoand

risposta

5

Sebbene non sia una risposta diretta alla tua domanda, tuttavia ti suggerisco di allontanarti dal campo di iniezione e utilizzare invece l'iniezione del costruttore (rende il codice più leggibile e verificabile).

Il codice sarà simile:

class Patient { 

    private final Syringe syringe; 

    @Inject 
    public Patient(Syringe syringe) { 
    System.out.println("That hurt like crazy!"); 
    } 

} 

Poi il test sarebbe semplicemente:

@RunWith(MockitoJUnitRunner.class) 
class TestCase { 

    @Mock 
    Syringe siringeMock; 

    Patient patient; 

    @Before 
    public void setup() { 
    patient = new Patient(siringeMock); 
    } 

} 

Aggiornamento

Come suggerito da Erik-Karl nei commenti, è possibile utilizzare @InjectMocks per sbarazzarsi del metodo di installazione. La soluzione funziona perché Mockito utilizzerà l'iniezione del costruttore appropriata (come descritto here). Il codice sarebbe quindi simile:

@RunWith(MockitoJUnitRunner.class) 
class TestCase { 

    @Mock 
    Syringe siringeMock; 

    @InjectMocks 
    Patient patient; 

} 
+1

Questo è MODO più verificabile, grazie doc! – gurghet

+0

@gurghet Benvenuto! – geoand

+3

Non solo è più testabile, ma si ottengono alcune garanzie sulla sicurezza dei thread facendo in modo che i campi siano definitivi. Si noti che anche con il codice precedente, è necessario chiamare manualmente il metodo '@ PostConstruct' – NamshubWriter

Problemi correlati