2013-06-06 31 views
7

Jestem zaskoczony. Próbuję przetestować klasę AspectJ. Moja klasa Aspect jest doskonale odbierana podczas uruchamiania aplikacji. Jednak wydaje mi się, że nie mogę uzyskać żadnej klasy Aspektu, która przechwyciłaby jakąkolwiek metodę w teście.Porada AspectJ nie jest wykonywana poprzez test jednostkowy

Używam Wiosna 3.2.2, 1.7.2 i Maven AspectJ 4.

Oto prosty test pracuję z: klasy

Test AspectJ

package my.package.path.config; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Pointcut; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

@Aspect 
public class TestAOP { 
    private String message; 

    public TestAOP() { 
    } 

    @Pointcut("execution(* my.package.path.TestAOPClient.relayMessage(..))") 
    public void aopPointcut() { 
    } 

    @Around("aopPointcut()") 
    public String monitor(ProceedingJoinPoint pjp) throws Throwable { 
     String msg = (String)pjp.proceed(); 
     this.setMessage(msg); 
     return msg; 
    } 

}

potrzeb klasy, którego metoda zostanie przechwycona

package my.package.path.config; 

public class TestAOPClient { 
    public String relayMessage(String msg) { 
     return msg; 
    } 
} 

klasa test

package my.package.path.config; 

import static org.hamcrest.Matchers.equalTo; 
import static org.junit.Assert.assertThat; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.web.WebAppConfiguration; 

@Configuration 
@ContextConfiguration(classes={WebConfig.class}) 
@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration("src/main/java") 
public class AopConfigTest extends AbstractJUnit4SpringContextTests { 

    @Bean 
    public TestAOP testAop() throws Exception { 
     return new TestAOP(); 
    } 

    @Test 
    public void assertTestConfigIsActive() { 
     TestAOPClient client = new TestAOPClient(); 
     client.relayMessage("hello"); 
     assertThat(((TestAOP)applicationContext.getBean("testAop")).getMessage(), equalTo("hello")); 

    } 
} 

Plik webconfig

package my.package.path.web.context; 
@Configuration 
@EnableWebMvc 
@EnableAspectJAutoProxy(proxyTargetClass=false) 
@ComponentScan(value={"my.package.path.config", "my.package.path.web"}) 
public class WebConfig { 

} 

Niezmiennie będę się błąd twierdzenie

Expected: "hello" but: was null 

Moja WebApplicationContext wydaje się być odebrany, ponieważ w czasie wykonywania, Otrzymam błąd ApplicationContext, który nie załaduje błędu, jeśli określę klasę, która nie istnieje dla mojego punktu cięcia w Aspect.

Czego mi brakuje?

Odpowiedz

5

To dziwne, że używasz testu jednostki również jako źródła @Configuration.

Należy usunąć adnotację @Configuration z testu urządzenia i przenieść definicję fasoli testAOP() na . Ale co najważniejsze fasoli są poinformowani nie muszą być tworzone ręcznie, ale wiosną:

@ContextConfiguration(classes={WebConfig.class}) 
@WebAppConfiguration("src/main/java") 
public class AopConfigTest extends AbstractJUnit4SpringContextTests { 

    @Autowired 
    private TestAOP testAop; 

    @Autowired 
    private TestAOPClient client; 

    @Test 
    public void assertTestConfigIsActive() { 
     client.relayMessage("hello"); 
     assertThat(((TestAOP)applicationContext.getBean("testAop")).getMessage(), 
      equalTo("hello")); 
    } 

} 

Updated config z definicją Fasola:

@Configuration 
@EnableWebMvc 
@EnableAspectJAutoProxy(proxyTargetClass=false) 
@ComponentScan(value={"my.package.path.config", "my.package.path.web"}) 
public class WebConfig { 

    @Bean 
    public TestAOP testAop() throws Exception { 
     return new TestAOP(); 
    } 

    @Bean 
    public TestAOPClient testAopClient() throws Exception { 
     return new TestAOPClient(); 
    } 

} 

Jeśli twoim celem było sprawdzenie, czy konfiguracja AOP działa i TestAOP jest naprawdę testującym komponentem bean (nie tylko fałszywą nazwą tego pytania), można utworzyć specjalną klasę konfiguracji TestConfig, przenieść definicję komponentu bean i użyć jej z testu @ContextConfiguration(classes={WebConfig.class,TestConfig.class}).

+1

Przeniosłem rzeczy zgodnie z sugestią.Wygląda czystsze. Ale nadal nie działa. W tej chwili mam wszystko poza moimi klasami testowymi w obszarze src/main/java kodu, podczas gdy sama klasa Test znajduje się w src/test/java. TestAOP jest opatrzony komentarzem w WebConfig. Czy to może być coś związanego z tym, kiedy i jak tkanie występuje podczas uruchamiania testu? Czy istnieje konfiguracja, którą muszę ustawić, aby to się stało? Jestem bardzo nowy w Spring. – Emilie

+1

Och, właśnie zauważyłem, że ręcznie tworzysz komponent bean docelowy w teście 'TestAOPClient client = new TestAOPClient();' ... to nie działa w ten sposób. Wiosna musi być tym, który tworzy ziarno! Zaktualizuję moją odpowiedź. –

+1

Odpowiedź zaktualizowana. –

1

Konfiguracja punktu przekroju jest źle (pakiet należy my.package.path.config pasujące do Twojego klienta testowego)

@Pointcut("execution(* my.package.path.TestAOPClient.relayMessage(..))") 

i klient jest

package my.package.path.config; 

public class TestAOPClient { 
... 

go zmienić na tym

@Pointcut("execution(* my.package.path.config.TestAOPClient.relayMessage(..))") 

powinien działać.

+1

To jest literówka od kiedy zmieniłem nazwę paczki, aby nie wystawiać nazwy firmy. Sprawdziłem pakiety i są one poprawne. – Emilie

+0

Dziękuję za tę odpowiedź. Miałem podobny problem jak w @Emilie, a moje wyrażenie "@ Pointcut" było ostatnim problemem, który uniemożliwiał działanie mojej porady "@ Before"! –

Powiązane problemy