2015-07-23 8 views
5

Ho un chicco di simile a questo:test di fagioli di primavera con il post costruire

@Service 
public class A { 
    @Autowired 
    private B b;  
    @PostConstruct 
    public void setup() { 
     b.call(param); 
    } 
} 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = { Application.class, Config.class }) 
@WebIntegrationTest(randomPort = true) 
public class Test { 
    @Autowired 
    B B; 
    @Before 
    public void setUp() throws Exception { 
     when(b.call(any())).thenReturn("smth"); 
    } 
    @Test 
    public void test() throws Exception { 
     // test... 
    } 
} 

Il problema è che PostConstruct viene chiamato prima setUp quando viene eseguito il test.

+0

@hzp z La classe A ha un'altra logica che viene chiamata in test. E rispondendo alla tua domanda vorrei testare la logica della classe A. – Andy

risposta

8

Se si desidera scrivere un unità test di A, quindi non utilizzare Spring. Invece, istanziare A e passare uno stub/mock di B (utilizzando l'iniezione del costruttore o ReflectionTestUtils per impostare il campo privato).

Ad esempio:

@Service 
public class A { 

    private final B b;  

    @Autowired 
    public A(B b) { 
     this.b = b; 
    } 

    @PostConstruct 
    public void setup() { 
     b.call(param); 
    } 
} 

-

public class Test { 

    @Test 
    public void test() throws Exception { 
     B b = mock(b); 
     A a = new A(b); 
     // write some tests for A 
    } 

} 

Se si deve usare primavera, perché si vuole scrivere un'integrazione prova , utilizzare un contesto di applicazione diversa, in cui si sostituisce B con uno stub/mock.

Per esempio, supponendo che B viene creata un'istanza in una classe Production come questo:

@Configuration 
public class Production { 

    @Bean 
    public B b() { 
     return new B(); 
    } 

} 

scrivere un'altra classe @Configuration per i test:

@Configuration 
public class Tests { 

    @Bean 
    public B b() { 
     // using Mockito is just an example 
     B b = Mockito.mock(B.class); 
     Mockito.when(b).thenReturn("smth"); 
     return b; 
    } 

} 

di riferimento nel vostro test con la @SpringApplicationConfiguration della nota:

@SpringApplicationConfiguration(classes = { Application.class, Tests.class }) 
+0

Grazie! Sì, è quasi giusto. Inoltre '@Configuration Test di classe pubblici { @Bean pubblica B B() { \t B b = Mockito.mock (B.class); \t Mockito.quando (b) .thenReturn ("smth"); ritorno b; } } ' – Andy

+0

questa prima parte della soluzione sta evitando il vero problema eliminando la parte" integrazione "del test. La seconda parte è molto meglio – cahen

+2

@chehen Ecco perché ho iniziato con "Se vuoi scrivere un ** test ** dell'unità". Nella mia esperienza, le persone tendono spesso a scrivere test di integrazione quando vogliono effettivamente un test unitario. – hzpz

Problemi correlati