2011-09-15 22 views
10

Mam testy integracyjne (kontekst obciążenia) i testy jednostkowe działające razem. Mój kod wykonuje kompresję czasu według sprężyny.Wyłączanie niektórych aspektów podczas testów jednostkowych

Moim problemem jest to, że moje zadeklarowane porady biegną również podczas niektórych testów jednostkowych. To zabija pojęcie testu jednostkowego, dlatego chciałbym je wyłączyć.

Czy jest coś, co mogę umieścić w deklaracji cięcia, jakiejś metodzie, którą mogę wywołać, konfiguracji wiosennej lub komendzie maven, która wyłącza te porady dla czegoś takiego jak wszystkie * UnitTest.java?

Dzięki za pomoc.


przykład:

mam następujący test jednostka:

@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)); 
    } 
} 

i po usługi Metoda:

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

aspekt: ​​

@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); 
    } 

} 

Po wykonaniu testu - eventJournalService ma wartość null. Tak więc widzę NullPointerException

Odpowiedz

0

Mogę tylko zgadywać: Pierwszą rzeczą jest mieć oddzielne Spring appContext-test.xml, bez skanowania składnika; W maven można dodać fazę wykonawczą, wyłączając słoiki do tkania do testu.

0

Skompilowanie czasu tkania będzie inline wywoływać porady w metodach docelowych określonych przez posiadane punkty. Osobiście uważam, że dobrze jest przeprowadzić test jednostkowy z czasem tkania kompilatora, ponieważ w czasie pracy jednostka zawiera klasę z poradą w linii prostej?

Myślą, której nie wolno mi doradzić, byłoby posiadanie dwóch różnych celów kompilacji, jednego z kompilacją czasu tkania, a jednego bez, powinieneś być w stanie to zrobić poprzez profile profilów, profil deweloperski, nie tkający porad i profil prod do splotu aspektów.

3

Odpowiedź jest prosta: chcesz użyć numeru if() pointcut expression.


Aktualizacja (po kwestia została również zaktualizowana): Pierwotnie podana odnośniki powyżej powinno zawierać wystarczającą ilość informacji, ale za to, co warto, krótkie wyjaśnienie i prosty przykład:

if() pointcut to metoda aspektu static zwracająca wartość boolean. Jeśli wartość zwracana to true, oznacza to, że wszystkie połączone punkty, takie jak myPointcut() && if(), pasują do siebie tak długo, jak myPointcut(). Dla wartości zwracanej false cały kombinowany punkt nie pasuje, skutecznie dezaktywując wszelkie porady związane z punktem.

Co można zrobić w punkcie statycznym o wartości?

  • ocenę statyczną logiczna członkiem jakiejś klasy narzędzie jak TestMode.ACTIVE która jest jedyną prawdziwą podczas testów jednostkowych lub integracji
  • ocenić zmiennej środowiskowej, która jest tworzona tylko podczas testowania
  • ocenić właściwości systemowe Java, który jest tylko ustawić podczas testowania
  • i wiele innych rzeczy

Jeśli chcesz zrobić coś bardziej wyszukane (i trudniejsze) i wydajność nie jest tak ważne, to c a także spróbuj dynamicznie określić, czy automatycznie okablowana zmienna składowa aspektu jest równa zeru, czy nie, i aktywować tylko punkty, jeśli obiekt wstrzyknięty jest rzeczywiście obecny. Jedyny problem polega na tym, jak określić zmienną składową z metody statycznej. Nie mam pojęcia o Spring AOP, ale w prostym AspectJ jest klasa pomocnika Aspects z kilkoma przeciążonymi metodami o nazwie aspectOf(..). Zakładając, że aspekt jest tworzony jako singleton, można zrobić coś takiego:

@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

proszę podać przykład – gstackoverflow

+0

Dodałem szczegóły do ​​pierwotnego postu. – gstackoverflow

+0

Jak możesz dodać szczegóły do ​​pytania, które nie są oryginalnym plakatem? – kriegaex

0

można napisać metodę, która zwraca jeśli prąd egzekucja została uruchomiona za pomocą ramy JUnit.

Metoda może sprawdzić ślad stosu za pomocą Thread.currentThread(). GetStackTrace() i wyszukać obecność MockitoJUnitRunner.

Przetestowałem to rozwiązanie przy użyciu SpringJUnit4ClassRunner, ale myślę, że może pracować z MockitoJUnitRunner.

Można również masz statycznego pola logiczną jak:

private static boolean TEST_ENVIRONMENT = false; 

w klasie obecnej w projekcie (nie w badaniach) i sprawdź wartość w sposobie sterowania zamiast śladu użycie stosu.

Po uruchomieniu testów można użyć adnotacji @BeforeClass do ustawienia parametru TEST_ENVIRONMENT = true.

To rozwiązanie zapewnia tylko sposób sprawdzenia, czy kod jest uruchamiany z testu, czy nie.

Powiązane problemy