강의

멘토링

로드맵

Inflearn Community Q&A

inf0257388's profile image
inf0257388

asked

Toby's Clean Spring - Domain Model Pattern and Hexagonal Architecture Part 1

Architecture Testing using ArchUnit

마지막 헥사고날아키텍쳐 테스트

Written on

·

41

0

마지막 강의에서 진행한 헥사고날 아키텍처 테스트에서 저는 아래와 같이 에러가 발생하고 있는데 어떻게 수정을 해야 할까요? 소스 코드는 동일한 것 같은데... 무엇이 차이인지 모르겠어요

13:09:39.840 [Test worker] INFO com.tngtech.archunit.core.PluginLoader -- Detected Java version 17.0.12

Architecture Violation [Priority: MEDIUM] - Rule 'Layered architecture considering all dependencies, consisting of

layer 'domain' ('com.inflearn.splearn.domain..')

layer 'application' ('com.inflearn.splearn.application..')

layer 'adapter' ('com.inflearn.splearn.adapter..')

where layer 'domain' may only be accessed by layers ['application', 'adapter']

where layer 'application' may only be accessed by layers ['adapter']

where layer 'adapter' may not be accessed by any layer' was violated (1 times):

Method <com.inflearn.splearn.SplearnTestConfiguration.passwordEncoder()> calls method <com.inflearn.splearn.domain.member.MemberFixture.createPasswordEncoder()> in (SplearnTestConfiguration.java:19)

java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'Layered architecture considering all dependencies, consisting of

layer 'domain' ('com.inflearn.splearn.domain..')

layer 'application' ('com.inflearn.splearn.application..')

layer 'adapter' ('com.inflearn.splearn.adapter..')

where layer 'domain' may only be accessed by layers ['application', 'adapter']

where layer 'application' may only be accessed by layers ['adapter']

where layer 'adapter' may not be accessed by any layer' was violated (1 times):

Method <com.inflearn.splearn.SplearnTestConfiguration.passwordEncoder()> calls method <com.inflearn.splearn.domain.member.MemberFixture.createPasswordEncoder()> in (SplearnTestConfiguration.java:19)

at com.tngtech.archunit.lang.ArchRule$Assertions.assertNoViolation(ArchRule.java:94)

at com.tngtech.archunit.lang.ArchRule$Assertions.check(ArchRule.java:86)

at com.tngtech.archunit.library.Architectures$LayeredArchitecture.check(Architectures.java:347)

at com.inflearn.splearn.HexagonalArchitectureTest.hexagonalArchitecture(HexagonalArchitectureTest.java:22)

at java.base/java.lang.reflect.Method.invoke(Method.java:569)

at com.tngtech.archunit.junit.internal.ReflectionUtils.invoke(ReflectionUtils.java:111)

at com.tngtech.archunit.junit.internal.ReflectionUtils.invokeMethod(ReflectionUtils.java:103)

at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor$ArchUnitMethodDescriptor.execute(ArchUnitTestDescriptor.java:203)

at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor$ArchUnitMethodDescriptor.execute(ArchUnitTestDescriptor.java:173)

at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

 

javaspringspring-bootjpa리팩터링ddd

Answer 2

0

tobyilee님의 프로필 이미지
tobyilee
Instructor

안녕하세요.

ArchUnit이 편리한 테스트 도구이긴 하지만 체크를 통과하지 못하고 예외가 발생하면 확인하기가 처음에는 쉽지 않습니다.

이런 실패를 만나면 먼저 어떤 클래스에서 발생한 문제인지 체크하고, 그리고 어떤 규칙을 위반했는지 이렇게 정보를 찾아야 합니다.

그런데 여기 등장한 클래스를 보니 SpringTestConfiguration이나 MemberFixture 같은 것들이 있네요. 이건 테스트 코드거든요. 우리가 아키텍처 체크를 할 때는 테스트 코드가 아닌 애플리케이션 코드, main 모듈의 코드에 대해서만 확인하는 것이 일반적입니다. 그런데 테스트 모듈의 클래스에 대해서 ArchUnit이 오류 메시지를 냈다는 것은 테스트 모듈은 제외해달라는 옵션이 빠졌기 때문으로 보입니다.

강의 예제의 해당 테스트는 다음과 같이 선언되어야 합니다.

@AnalyzeClasses(packages = "tobyspring.splearn", importOptions = ImportOption.DoNotIncludeTests.class)
public class HexagonalArchitectureTest {

여기서 DoNotIncludeTests라는 부분이 테스트 모듈은 검사 대상에서 제외해달라는 것인데요. 이 부분이 빠졌거나 잘못 들어갔으면 위와 같은 에러가 발생할 것입니다. 확인해보세요.

0

안녕하세요, 인프런 AI 인턴입니다.

inf025님께서 겪고 계신 문제는 헥사고날 아키텍처에 관한 테스트 시, 아키텍처 간 의존성 위반으로 인해 발생한 것으로 보입니다. 이 오류는 특정 레이어가 허용되지 않은 다른 레이어와 상호작용을 했기 때문입니다. 주어진 메시지에서, SplearnTestConfiguration.passwordEncoder() 메서드가 com.inflearn.splearn.domain.member.MemberFixture.createPasswordEncoder() 메서드를 호출하면서 위반이 발생하고 있습니다.

헥사고날 아키텍처는 각 레이어가 명확하게 분리되어 있어야 하며, 레이어 간의 의존성 규칙이 지켜져야 합니다. 특히, 도메인 레이어는 상위 레이어들(application, adapter 등)에서만 접근할 수 있어야 합니다. 이런 규칙을 위반하면 아키텍처 검증에서 실패합니다.

해결 방법:

  1. 레이어 의존성 확인: SplearnTestConfiguration.passwordEncoder()createPasswordEncoder()를 호출하지 않도록 변경해야 합니다. 비즈니스 로직과 테스트 구성은 명확히 분리되어야 합니다. 이로 인해 dependency injection 방식 또는 다른 방법을 사용할 수 있습니다.

  2. Mock 객체 사용: 테스트 시에는 실제 객체 대신 모킹(Mocking)된 객체를 사용하는 것이 좋습니다. 이를 위해 Mockito 등을 활용하여 createPasswordEncoder()에 대한 모킹 객체를 만들어 사용해보세요.

  3. 구성 설정 분리: SplearnTestConfiguration이 실제 비즈니스 로직에 접근하지 않도록, 테스트 전용 설정을 분리되게 구성하는 것이 필요합니다.

또한 다른 수강생들이 유사한 상황을 겪은 사례가 있으니 아래 게시물을 참고하세요:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

inf0257388's profile image
inf0257388

asked

Ask a question