모종닷컴

Mock Layer 본문

Programming/Spring

Mock Layer

모종 2022. 8. 17. 22:32
반응형

3계층 구조

  • Presentation Layer : 사용자 중점 계층 (front-end)
  • Business Layer : 비즈니스 로직 계층, presentation layer의 요구를 받아 처리하는 곳 (back-end)
  • Data Layer : 데이터베이스에 접근하여 데이터를 읽거나 쓰는 작업등의 역할

Mock Layer란?

Mock Layer라는 개념이 존재하는 것은 아니고 제가 임의로 편하게 부르기 위해서 지어봤습니다. 위의 3계층 구조에서 Business Layer에 속하게 됩니다.

테스트 코드를 짜다보면 mockito 라는 테스트 프레임워크에 대하여 한번쯤은 들어보셨을 겁니다. 어떤 특정 요청에 대하여 개발자가 지정한 결과를 내려주는 방식인데 이러한 것을 실행 환경에서도 사용하기를 원했습니다. 한마디로 개발 환경에서만 작동했으면 하는 특정 로직을 실행하는 가짜 객체정도라고 생각하면 좋을 것 같습니다. 그 속에서도 아래와 같은 규칙을 지키고 싶었습니다.

  1. 프로덕션 환경에서는 작동하지 않으며, 개발 환경에서만 적용됬으면 좋겠다.
  2. 기존에 존재하는 코드들에 하드 코딩을 하기 싫었다. ex) 로직 주석 처리 후 return "";
  3. Mock Layer 에서 로직이 실패했을 때에는 실제 객체에 다시 요청되게 만들어야 한다.

Sample Code

아래는 샘플 코드입니다.

https://github.com/kimjongmo/mock-layer

Profile

스프링 부트에는 프로파일이라는 개념이 존재합니다. 각각의 코드에 대하여 @Profile 이라는 어노테이션과 함께 이름을 지정 후 프로젝트를 실행시킬 때 어떤 프로파일들을 실행시킬 건지 선언하면 해당하는 클래스만 생성되어 빈이 올라가게 됩니다.

만약 위 사진과 같이 dev profile을 지정한다면 ItemServiceImpl , MockItemServiceImpl이 빈으로 올라가게 되고, product 프로파일을 지정한다면 ItemServiceImpl만 빈으로 올라가게 될 것입니다.

Primary Bean

현재 ItemService를 구현하고 있는 ItemServiceImpl, MockItemServiceImpl이 있는데 이럴 경우 itermService에 대하여 주입을 받으려 할 때 (물론 리스트로 받으면 구현체 모두를 가져올 수 있지만..) 여러 개의 빈이 존재할 경우 구체적으로 내가 어떤 빈을 사용할 것인지 명시를 해줘야 합니다. 내가 어떤 빈을 사용할 것인지 명시하는 방법은 여러가지가 있습니다.

  • 사용하려는 빈의 이름을 변수로 선언
  • @Qualifier를 이용해서 빈을 지정
  • 각각의 구현체에 우선 순위를 부여

우리의 상황을 생각해보면 dev 일 때에는 MockItemServiceImpl이 붙어야 하고, product일 때는 itemServiceImpl을 주입받아야 합니다. 그러므로 특정 빈의 이름을 지정해서 사용할 수는 없습니다. 그래서 구현체에 우선순위를 부여할 것입니다. mockItemServiceImpl과 itemServiceImpl 두 개의 빈이 생성되었을 때에는 mock이 우선순위가 높아야하므로 MockItemServiceImpl에는 @Primary 를 붙여 우선순위를 제일 높게 잡아줍니다.

Proxy

MockItemServiceImpl에서 만약 mock 대상이 아니라면 실제 객체인 ItemServiceImpl 에 연결해주기 위해서 프록시와 같은 형태로 만들었습니다.

mockRepository에서 요청 데이터를 찾을 수 없다면 실제 객체로 재요청하게 될겁니다.

여기서 바로 위에서 말한 빈 명시를 해줘야 하므로 실제 객체는 아래와 같은 방식으로 주입받도록 해야합니다.

Test

profile을 dev, product 번갈아가면서 http://localhost:8080/item/1 을 요청해보면서 mock layer가 동작하는지 확인해보세요.

반응형