You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
필자는 Spring Security 를 사용하지 않고, User Role 에 따라 실행될 수 있는 Method 를 분리하고 싶었다.
User Role 에 따른 실행 가능한 Method 의 분리를 생각했을 때, Controller Layer 에서 요청으로 전달받은 Token 의 분해와 해당 Token 의 Claims 에 포함되어있는 Role 을 가져와야됐다.
여기에서 도출된 내 고민은 "과연 이 Logic이 Controller Layer 에 있어야되나?" 라는 고민이었다.
검증에 관련된 로직은 Security 도메인에서 관리하게 설정하고 싶었고, 이에 따라 Annotation 으로 관리하자는 결론을 내리게 되었다.
Annotation 으로 관리를 하여서, HandlerMethodArgumentResolver 로 따로 빼내는 생각을 1차적으로 하였는데, 그렇게 할 경우, Parameter 에 무의미한 값을 가져올 가능성이 있었다.
따라서 이를 AOP 로 작성하면 관심사 분리도 될 뿐 더러, 여러 방면으로 사용될 가치가 있을 거라는 판단하에 AOP 를 작성하게 되었다.
하지만 필자는 AOP 를 처음 작성해보기도 하였고, 이때까지 AOP 를 적극적으로 이용해본 경험이 많이 없었다..😭
같이 프로젝트를 진행하는 팀원들에게 필자가 작성한 Logic 에 대해서 신뢰를 얻기 위해 Test 코드를 작성하게 되었는데, 대부분의 예제들은 Mockito 나 @SpringBootTest 를 이용하여 통합테스트로 진행하는 것을 볼 수 있었다.
이 과정은 Test 가 느려질 뿐 더러, Jobmanri 프로젝트는 JDBC Repository 를 사용하고 있어, 통합테스트를 사용하는 부분이 많아 사용하기 꺼려졌다..
( 기왕이면 최대한 필요한 부분에 대해서만 통합 테스트를 진행하고 싶은 필자의 욕심이 조금 담겨있음. )
따라서 Insight 를 찾아보던 중, 단위테스트를 통해서 Aspect 를 테스트한 문서가 있어, 해당 문서를 참고하여 테스트 코드를 작성하게 되었다.
내용(内容)
제목이 Mockito 없이 순수 Java 로 AOP 단위 테스트를 진행해보았다고 해놨는데, 구체적으로 SpringBootTest 또한 진행하지 않았다.
이렇게 테스트가 진행할 수 있었던 조건은 아래와 같다.
Bean 이나 JPA 에 의존하지 않는 기능
Java 에 기존 내장되어 있는 RequestContext 를 이용한 기능 탑재
해당 글을 이해하기 위해서 Jobmanri 의 @PreAuthorize 가 어떤 Flow 로 진행되는 지 알면 좋을 것 같아서 AI 를 통해서 플로우만 맛보기로 보도록 하자.
위의 로직을 보면, Test 코드를 작성할 때, ServletRequest 에 대해서 접근하는 부분이 있는 것을 확인할 수 있다.
그래서 해당 로직을 테스트하기 위해서는 ServletRequest 을 구현해야만하는 단점이 있었다.
아마 ServletRequest Interface 를 확인하면, 꽤나 많은 Method 를 구현해야하는 것을 알 수 있는데,,
이를 다 구현하는 것 또한 방법이겠지만, 그렇게 되면 Test 코드에 대해서 많은 시간을 투자하게 된다.. ( 기능 구현하기에도 바쁜데,,🫠 )
따라서 ServletRequest 인스턴스 역할을 하는 Proxy 객체를 아래와 같이 제작하기로 하였다.
왜냐하면 필요한 Method는 attributes 를 설정하고, 가져오는 것, 그리고 Header 에 들어있는 Authorization 을 가져오기 위함이기 때문이다.
추가적으로 Aspect 에 들어가는 Parameter 인 ProceedingJoinPoint 와 PreAuthorize 어노테이션을 전달해주기 위해서 이들에 대한 Fake 객체 또한 만들어줘야했다.
PreAuthorize 와 같은 어노테이션에 대해서 Fake 객체를 만들어주기 위해서는 Annotation 또한 interface 이기에, Proxy 객체로 구현체를 만들어주는 방법밖에 떠오르지 않았다. ( 이에 대해서 만약 개선점이 필요할 것 같은 기분...🫠 )
또한 ProceedingJoinPoint interface 도 구현체를 만들어줘야했기에 Proxy 로 구현체를 만들어주기로 결심하였다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Mockito 없이 순수 Java 로 AOP 에 대해서 단위 테스트를 진행해보았다.
개요( 概要 )
필자는 Spring Security 를 사용하지 않고, User Role 에 따라 실행될 수 있는 Method 를 분리하고 싶었다.
User Role 에 따른 실행 가능한 Method 의 분리를 생각했을 때, Controller Layer 에서 요청으로 전달받은 Token 의 분해와 해당 Token 의 Claims 에 포함되어있는 Role 을 가져와야됐다.
여기에서 도출된 내 고민은 "과연 이 Logic이 Controller Layer 에 있어야되나?" 라는 고민이었다.
검증에 관련된 로직은 Security 도메인에서 관리하게 설정하고 싶었고, 이에 따라 Annotation 으로 관리하자는 결론을 내리게 되었다.
Annotation 으로 관리를 하여서, HandlerMethodArgumentResolver 로 따로 빼내는 생각을 1차적으로 하였는데, 그렇게 할 경우, Parameter 에 무의미한 값을 가져올 가능성이 있었다.
따라서 이를 AOP 로 작성하면 관심사 분리도 될 뿐 더러, 여러 방면으로 사용될 가치가 있을 거라는 판단하에 AOP 를 작성하게 되었다.
하지만 필자는 AOP 를 처음 작성해보기도 하였고, 이때까지 AOP 를 적극적으로 이용해본 경험이 많이 없었다..😭
같이 프로젝트를 진행하는 팀원들에게 필자가 작성한 Logic 에 대해서 신뢰를 얻기 위해 Test 코드를 작성하게 되었는데, 대부분의 예제들은 Mockito 나 @SpringBootTest 를 이용하여 통합테스트로 진행하는 것을 볼 수 있었다.
이 과정은 Test 가 느려질 뿐 더러, Jobmanri 프로젝트는 JDBC Repository 를 사용하고 있어, 통합테스트를 사용하는 부분이 많아 사용하기 꺼려졌다..
( 기왕이면 최대한 필요한 부분에 대해서만 통합 테스트를 진행하고 싶은 필자의 욕심이 조금 담겨있음. )
따라서 Insight 를 찾아보던 중, 단위테스트를 통해서 Aspect 를 테스트한 문서가 있어, 해당 문서를 참고하여 테스트 코드를 작성하게 되었다.
내용(内容)
제목이 Mockito 없이 순수 Java 로 AOP 단위 테스트를 진행해보았다고 해놨는데, 구체적으로 SpringBootTest 또한 진행하지 않았다.
이렇게 테스트가 진행할 수 있었던 조건은 아래와 같다.
해당 글을 이해하기 위해서 Jobmanri 의 @PreAuthorize 가 어떤 Flow 로 진행되는 지 알면 좋을 것 같아서 AI 를 통해서 플로우만 맛보기로 보도록 하자.

위에서 AOP 가 어떻게 적용되는지 알 수 있었으므로, 구체적인 로직에 들어가자.
위의 로직을 보면, Test 코드를 작성할 때, ServletRequest 에 대해서 접근하는 부분이 있는 것을 확인할 수 있다.

그래서 해당 로직을 테스트하기 위해서는 ServletRequest 을 구현해야만하는 단점이 있었다.
아마 ServletRequest Interface 를 확인하면, 꽤나 많은 Method 를 구현해야하는 것을 알 수 있는데,,
이를 다 구현하는 것 또한 방법이겠지만, 그렇게 되면 Test 코드에 대해서 많은 시간을 투자하게 된다.. ( 기능 구현하기에도 바쁜데,,🫠 )
따라서 ServletRequest 인스턴스 역할을 하는 Proxy 객체를 아래와 같이 제작하기로 하였다.
왜냐하면 필요한 Method는 attributes 를 설정하고, 가져오는 것, 그리고 Header 에 들어있는 Authorization 을 가져오기 위함이기 때문이다.
이렇게 Fake Reqeust Servlet 을 만들 수 있게 되었고, 아래처럼 코드를 작성할 수 있게 되었다.
추가적으로 Aspect 에 들어가는 Parameter 인 ProceedingJoinPoint 와 PreAuthorize 어노테이션을 전달해주기 위해서 이들에 대한 Fake 객체 또한 만들어줘야했다.
PreAuthorize 와 같은 어노테이션에 대해서 Fake 객체를 만들어주기 위해서는 Annotation 또한 interface 이기에, Proxy 객체로 구현체를 만들어주는 방법밖에 떠오르지 않았다. ( 이에 대해서 만약 개선점이 필요할 것 같은 기분...🫠 )
또한 ProceedingJoinPoint interface 도 구현체를 만들어줘야했기에 Proxy 로 구현체를 만들어주기로 결심하였다.
따라서 아래처럼 코드를 작성하게 되었다.
마지막으로 테스트를 실행해보았을 때, 아래처럼 성공하는 것을 볼 수 있다.
여기에서 속도는 175ms 로 나와있는데, 다른 통합테스트에 비해서 속도를 비교해보면 4배정도 빠른 것을 볼 수 있다.

엄청나게 드라마틱한 변화는 아니지만, 통합테스트를 추가하지않고, 순수 Java로만 Test Code 를 작성해본 것에 대해서 의의를 두고, 이 포스팅을 마치고자 한다.
Reference
Beta Was this translation helpful? Give feedback.
All reactions