Spring AOP 단위 테스트를 수행하는 방법

하고 싶은 일



Spring AOP로 만든 업무 횡단적인 처리를 가진 클래스를 단독으로 테스트하고 싶다.

Spring AOP의 작동 방식(자연)과 단위 테스트 시의 문제점



Spring AOP는 DI를 기반으로 성립되어 있어 컴퍼넌트를 사용하는 측이 proxy(컨테이너에 등록한 Bean 그 자체가 아니고, 그 Bean에 대해서 AOP로 정의한 기능을 확장(enhance)시킨) 인스턴스를 인젝트 하는 것 에 의해 AOP를 실현합니다.


그러나 이번에 하고 싶은 것은 단위 테스트이므로, DI 컨테이너를 기동시키지 않고, 문맥에 의존하지 않고 테스트를 하는 방법을 준비하고 싶습니다.

이번에 준비한 샘플



인수에 null 가 있으면 NullPointerException 를 던지는 처리를 AOP로 구현해, TestService (테스트용 클래스) 클래스의 메소드에 적용시킵니다. (NullCheck 어노테이션은 단순한 마커이므로 여기서는 생략합니다.)

AspectLogic.java

@Aspect
@Component
public class AspectLogic {
    @Around("@annotation(NullCheck)")
    public Object invoke(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("NullCheck!!");
        Stream.of(proceedingJoinPoint.getArgs()).forEach(Objects::requireNonNull);//全引数を取得してObejcts::requireNonNullでチェック
        return proceedingJoinPoint.proceed();
    }
}


TestService.java

public class TestService {
    @NullCheck
    public void doSomething(Object arg) {
    }
}

AspectJProxyFactory에서 프록시를 가져옵니다.



Spring DI가 Bean에서 프록시를 얻는 부분을 직접 구현해 봅시다. AspectJProxyFactory 인스턴스
에 이번에 만든 Aspect 클래스를 add합니다.
팩토리로부터 취득한 proxy를 사용해 테스트 샘플 메소드를 두드리면, AOP로 정의한 처리가 불려 NullPointerException 가 던져지고 있는 것을 확인할 수 있었을까 생각됩니다.

TestAspectLogic.java
public class TestAspectLogic {
    @Test
    public void testAspect() {

        AspectJProxyFactory factory = new AspectJProxyFactory(new TestService());
        factory.addAspect(new AspectLogic()); //ここでAspectLogicクラスを適用
        TestService proxy = factory.getProxy();

        try {
            proxy.doSomething(null);
            failBecauseExceptionWasNotThrown(NullPointerException.class);
        } catch(NullPointerException npe) {
        }

    }
}


출력
NullCheck!!

요약



AOP도 제대로 테스트를 작성합시다.

좋은 웹페이지 즐겨찾기