2011-09-15 11 views
10

I test di integrazione (contesto di carico) e unit test funzionano insieme. Il mio codice esegue l'aspetto compilando il tempo usando la molla.Disattivazione di alcuni aspetti durante le prove di unità unitarie

Il mio problema è che i miei consigli dichiarati vengono eseguiti anche durante alcuni dei miei test di unità. Questo uccide la nozione di un test unitario, motivo per cui mi piacerebbe disabilitarli.

C'è qualcosa che posso inserire nella dichiarazione del pointcut, un metodo che posso chiamare, qualche configurazione di primavera o un comando di maven che disabilita questi consigli per qualcosa come tutto * UnitTest.java?

Grazie per l'aiuto.


esempio:

ho la seguente prova di unità:

@RunWith(MockitoJUnitRunner.class) 
public class CompanyServiceImplTest { 
    @Test 
    public void createCampaignTest() throws Exception { 
     when(companyDaoMock.saveCompany(any(Campaign.class))).thenReturn(77L); 

     Long campaignId = companyService.createCampaign(campaignMock); 

     assertEquals(Long.valueOf(77L), Long.valueOf(campaignId)); 
    } 
} 

e servizio seguente metodo:

@Override 
@Transactional 
@EventJournal(type = EventType.CAMPAIGN_CREATE, owner = EventOwner.TERMINAL_USER) 
public Long createCampaign(Campaign campaign) { 
    return companyDao.saveCompany(campaign); 
} 

aspetto:

@Aspect 
public class EventJournalAspect { 

    @Autowired 
    private EventJournalService eventJournalService; 

    @Pointcut(value="execution(public * *(..))") 
    public void anyPublicMethod() {} 

    @Pointcut("within(com.terminal.service..*)") 
    private void inService() {} 

    @AfterReturning(pointcut = "anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", returning = "id") 
    public void process(Object id, EventJournal eventJournal, AbstractDomainEntity entity) 
      throws Throwable { 
     if (eventJournal.type() != EventType.CAMPAIGN_PAYMENT || id != null) { 
      saveEvent(eventJournal, EventStatus.SUCCESS, entity, (Long) id); 
     } 
    } 

    @AfterThrowing(pointcut = "anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", throwing="ex") 
    public void processException(EventJournal eventJournal, AbstractDomainEntity entity, Exception ex) throws Throwable { 
     saveEvent(eventJournal, EventStatus.FAILURE, entity, null); 
    } 

    private void saveEvent(EventJournal eventJournal, EventStatus status, AbstractDomainEntity entity, Long persistentId) { 
     EventType type = eventJournal.type(); 
     EventOwner owner = eventJournal.owner(); 
     eventJournalService.saveEvent(type, owner, EventStatus.SUCCESS, entity, persistentId); 
    } 

} 

All'esecuzione del test - eventJournalService è nullo. Così vedo NullPointerException

risposta

0

posso solo immaginare: La prima cosa è quello di avere un separato Primavera applicationContext-test.xml, senza componente-scan; In Maven è possibile aggiungere un runtime di fase escludendo i vasi di tessitura per il test.

0

La tessitura del tempo di compilazione incorpora le chiamate di avviso nei metodi mirati identificati dalle scelte che avete. Personalmente ritengo che sia bene testare unitamente il tempo di compilazione, perché in fase di runtime la tua unità include la classe con il consiglio in linea?

Il pensiero che ho di non includere consiglio sarebbe quello di avere due diversi target di compilazione, uno con il tempo di tessitura di compilazione, e uno senza, si dovrebbe essere in grado di fare questo attraverso profili di Maven, un profilo dev non tessitura consulenza e un profilo per tessere gli aspetti.

3

La risposta è semplice: si desidera utilizzare un if() pointcut expression.


Aggiornamento (dopo che la questione è anche stata aggiornata): il collegamento in origine fornito sopra deve contenere informazioni sufficienti, ma per quello che vale la pena, una breve spiegazione e un semplice esempio:

An if() pointcut è un metodo di aspetto static che restituisce un boolean. Se il valore restituito è true, significa che qualsiasi combinazione di punti come myPointcut() && if() corrisponde a myPointcut() corrispondenze. Per un valore di ritorno di false l'intero punto di collegamento combinato non corrisponde, disattivando efficacemente qualsiasi consiglio connesso al punto di connessione.

Quindi cosa si può fare in un punto di riferimento statico if()?

  • valutare un membro booleana statica di una classe strumento come TestMode.ACTIVE che è vero solo in unità o test di integrazione
  • valutare una variabile d'ambiente che viene impostato solo durante i test
  • valutare una proprietà di sistema Java che è solo impostato durante il collaudo
  • e molte altre cose

Se si vuole fare qualcosa di più elaborato (e più difficile) e le prestazioni non è così importante, è c inoltre, si tenta di determinare dinamicamente se la variabile del membro di aspetto con cablaggio automatico è uguale a null o meno e attivare solo i propri collegamenti se l'oggetto iniettato è effettivamente presente. L'unico problema qui è come determinare una variabile membro da un metodo statico. Non ho idea di Spring AOP, ma in AspectJ è disponibile la classe helper Aspects con diversi metodi di overload denominati aspectOf(..). Supponendo che il vostro aspetto è istanziato come Singleton, si potrebbe fare qualcosa di simile:

@Pointcut("if()") 
public static boolean isActive() { 
    return Aspects.aspectOf(PerformanceMonitorAspect.class).eventJournalService != null; 
} 

// ... 

@AfterReturning(pointcut = "isActive() && anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", returning = "id") 
// ... 

@AfterThrowing(pointcut = "isActive() && anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", throwing="ex") 
// ... 
+0

si prega di fornire l'esempio – gstackoverflow

+0

Ho aggiunto dettagli al post originale. – gstackoverflow

+0

Come potresti aggiungere dettagli a una domanda di cui non sei il manifesto originale? – kriegaex

0

è possibile scrivere un metodo che restituisce se l'esecuzione corrente è stato avviato utilizzando il framework JUnit.

Il metodo può controllare la traccia di stack con Thread.currentThread(). GetStackTrace() e cercare la presenza di MockitoJUnitRunner.

Ho provato questa soluzione utilizzando uno SpringJUnit4ClassRunner ma penso che potrebbe funzionare con MockitoJUnitRunner.

Inoltre, è possibile hai un campo booleano statico come:

private static boolean TEST_ENVIRONMENT = false; 

In una classe presente nel progetto (non nei test) e controllare il valore nel metodo di controllo, invece di traccia dell'uso dello stack.

Quando si eseguono i test, è possibile utilizzare l'annotazione @BeforeClass per impostare TEST_ENVIRONMENT = true.

Questa soluzione fornisce solo un modo per sapere se il codice è in esecuzione da un test o meno.

Problemi correlati