본문 바로가기

FrontEnd

리액트와 유닛 테스트를 위한 클린 아키텍처 [부제, 의존성 주입은 정말 필요한가?]

반응형

아래 글에 포함하려다 따로 떼내어 적습니다.

https://itchallenger.tistory.com/771

 

헥사고날 아키텍처와 관심사의 분리를 이용한 클린 코드

1. 어니언, 헥사고날 아키텍처 헥사고날, 어니언 아키텍처는 port, adaptor 패턴의 별칭일 뿐입니다. https://blog.ploeh.dk/2016/03/18/functional-architecture-is-ports-and-adapters/ Functional architecture..

itchallenger.tistory.com

리액트의 모든 컴포넌트 인터페이스는 다음과 같이 추상화 할 수 있습니다.

<T=any>(props:React.ChildrenWithProps<T>)=>React.ReactNode

하지만 보통 구체적인 구현체인 평션 컴포넌트를 임포트해서 리턴값에서 사용하죠.

 

nest.js나 스프링의 경우 인터페이스 <-> 구체 클래스 매핑 정보를 리플렉션(애노테이션, 데코레이터)을 통해 IOC 컨테이너가 알고 있습니다.

리액트는 IOC 컨테이너가 없으니 컨텍스트 API가 없으면 인터페이스 기반으로만 프로그래밍 할 수 없죠.

 

그렇다면 리액트는 어떻게 구현체(Impl)를 바꿔가며 테스트할까요?

사실 함수가 순수하다면 DI를 굳이 사용할 필요가 없습니다.

컨트롤러의 인터페이스를 굳이 안만드는 것과 비슷하죠

하지만 부수효과를 포함한 순수하지 않은 컴포넌트의 경우 DI를 해주는 것이 좋습니다.

 

이를 위한 도구가 컨테이너 컴포넌트 + Context API 입니다.

컨테이너 컴포넌트는 프롭으로 주입받는 대신,

내부에서 하위 프레젠테이션 컴포넌트를 위한 의존성을 처리하는 역할을 합니다.

즉, 프리젠테이셔널 컴포넌트에 데이터와 콜백을 제공하는 역할을 수행하죠.

(데이터 + 메서드 = 뷰모델?)

(리액트-리덕스도 안정적인 참조를 컨텍스트 API를 통해 전달합니다.)

프리젠테이셔널 컴포넌트는 렌더링 로직과 스타일을 처리합니다.

즉 관심사의 분리가 잘 일어난거죠.

 

물론 요새는 두 개를 분리할 필요가 없다는 분들도 많습니다만,

이에 대한 내용을 아주 잘 설명하는 영상이 있으니, 참고하시기 바랍니다.

(제목 : 주객전도 아키텍처 / 프로그래밍)

https://www.youtube.com/watch?v=TW4cOAmRTFY 

개인적으로 저는 컨테이너 / 프리젠테이셔널 컴포넌트는 유닛 테스트를 위한 아키텍처를 넘어,

렌더링, 스타일, 마크업 구조와 데이터, 콜백 인터페이스의 관심사의 분리를 위해 반드시 필요하다 생각합니다.

그래서 어떻게 구현하나요?

위 영상을 보고오셨셨다면...

1. 저는 컨테이너, 프리젠테이셔널 컴포넌트 분리가 필요 없다 생각해요

아래 링크를 참조하시면 됩니다.

친절하게 위 영상의 핵심을 정리해드리자면,
꼭 유닛 테스트를 위해 설정을 바꾸는게, 자바 엔지니어들의 주장처럼 DI를 통해서만 이루어질 필요가 없다는 것입니다.
이는 때때로 불필요한 추상화와 인터페이스를 도입합니다.
런타임은 런타임이고, 테스트는 런타임의 문제를 해결하기 위한 수단입니다.
테스트가 런타임 아키텍처에 영향을 준다면 주객전도 입니다.

https://kentcdodds.com/blog/stop-mocking-fetch

 

Stop mocking fetch

Why you shouldn't mock fetch or your API Client in your tests and what to do instead.

kentcdodds.com

참고로 위 방법은 아래 2번 방법을 쓰지 않을 것이라면, 컨테이너, 프리젠테이셔널 컴포넌트 패턴에서도 그대로 쓸 수 있습니다.

2. 저는 컨테이너, 프리젠테이셔널 컴포넌트 구조로 짜고 싶고, 프레임워크, 라이브러리없이 유닛테스트 하고 싶어요!

아래 링크를 참조하시면 됩니다.

부수효과를 포함한 컨테이너 컴포넌트 자체의 구현을 바꿔 테스트 하는 방식입니다.

https://itchallenger.tistory.com/716

 

스토리북 개발팀이 알려주는 컨테이너 / 프리젠터 패턴 - Context API를 이용해 의존성 주입하기

스토리북 공식 문서에서 container / presenter 패턴의 사용 사례에 대해 배워봅니다. 스토리북을 전혀 몰라도 패턴에 대해 배우실 수 있습니다. 페이지(화면)을 만드는 방법 BBC, Guardian 및 Storybook 유지

itchallenger.tistory.com

 

2.1 컨테이너 컴포넌트 구조 잘 만드는 방법 알려주세요.

아래 예제를 참고하시면 됩니다.

2.2 프리젠테이셔널 컴포넌트 구조 잘 만드는 방법 알려주세요.

이는 다음 글의 주제가 될 것 같습니다.

 

참고

https://wit.nts-corp.com/2021/08/11/6461

 

React에서 View의 렌더링 관심사 분리를 위한 VAC 패턴 소개 | WIT블로그

React에서 View의 렌더링 관심사 분리를 위한 VAC 패턴 소개 시작하며 FE개발에서 View는 정보의 시각화 뿐만 아니라 사용자와 상호작용하는 역할을 포함하고 있습니다. 그래서 View를 개발하는 것은

wit.nts-corp.com

 

반응형