TIL

20221203 TIL 테스트의 독립성을 어떻게 보장하면 좋을까?

jiwoosmile 2022. 12. 3. 17:41

 

메가테라 과정을 수강하면서 가장 신기했던 부분은

프론트에서 (전역) 상태 관리를 다른 어떠한 외부 라이브러리 없이 구현을 했다는 점이었다.

구독 형식으로 listener를 등록해두고, store에서 상태를 바꾼 뒤에 publish를 하면

구독하고 있는 컴포넌트들이 리렌더링되면서 바뀐 상태가 반영되는 방식이다.

 

이를 활용하면 객체지향적으로 상태 관리를 할 수 있다는 장점이 있는데,

사용을 하다가 테스트가 조금 이상하게 동작하는 것을 발견하게 되어서 분석을 해봤더니 

이 방식을 사용하면서 테스트를 독립적으로 돌리기 위해 고려할 점이 있다는 것을 알게 되었다.

 

일관적인 상태 관리를 위해 모든 컴포넌트가 동일한 store를 사용해야하기 때문에 싱글톤 방식으로 동작하고 있는데,

이 싱글톤 방식으로 동작한다는 것이 테스트를 할 때도 그대로 적용되어

앞쪽 테스트에서 store에 준 변화가 뒤쪽 테스트를 할 때도 그대로 적용이 되는 문제가 있었다.

 

그래서 테스트들의 배치 순서에 따라 어쩔 때는 원하는대로 다 통과를 했다가

다른 방식으로 하면 문제가 없어야하는데도 불구하고 실패를 하는 경우가 있었다.

 

각 테스트는 독립적으로 돌아가야 한다.

테스트 순서에 따라 테스트 결과가 바뀌는 것은 매우 바람직하지 못하고, 정확한 테스트 결과를 보장해주지 못한다.

따라서 내가 할 수 있는 선택지들을 생각해보았다.

 

1. 모킹하기

당연히 가장 먼저 떠오른 것은 모킹이었다.

모킹을 하고 테스트마다 jest.clearAllMocks 해주면 내가 완벽히 통제를 할 수 있고, 매번 독립성도 보장할 수 있다.

문제는 store를 한 두 개 사용하는 것이 아닌데, 거의 스토어를 다시 창조하는 느낌으로

이 모든 것을 모킹을 하는 것이 바람직한가. 라는 고민과,

해줘야 하는 모킹이 한 두 개가 아니라서 모킹이 너무 괴로운 것 같다는 점 때문에 다른 방법을 고민하게 되었다.

https://www.youtube.com/watch?v=RoQtNLl-Wko

 

2. reset 메서드를 jest.clearAllMocks처럼 테스트 실행 전마다 실행해주기.

물론 이것보다 더 좋은 방식이 있을 수 있고, 어쩌면 모킹이 더 나은 방법일 수도 있지만

지금 내가 떠올릴 수 있는 가장 좋은 방법은 테스트마다 매번 store 필드를 리셋해주는 것이었다.

메서드를 사용해서 테스트를 진행한다는 것이 살짝 찜찜했지만, 

 

3. 모킹을 하되 매우 깔끔하게!

2번으로 적용을 한 채로 이 글을 작성하다보니

훅을 사용할 때 매번 새로운 Store를 만들어주면 되겠다는 생각에 아래와 같이 모킹을 해주었다.

처음에 1번에서 내가 생각한 방식은 내가 필요한 모든 것을 모킹해주는 것이었는데,

힘들 것 같아서 다른 방법을 찾다보니 Store를 매번 새롭게 만들어주면 된다는 생각이 들었고,

글로 내 생각을 정리하다보니 위와 같은 방식으로도 모킹을 해줄 수 있다는 것을 떠올리게 되었다.

당연히 이보다도 좋은 방식이 있을 수도 있겠지만,

store의 메서드를 사용하는 2번보다는 훨씬 마음에 드는 방식을 찾은 것 같다.

 

역시 일단 돌아가게 하고 리팩토링을 하는 것은 진리이다.

처음부터 좋은 방식을 떠올리려고 시간을 많이 쓰기 보다는

일단 돌아가게 하고, 글을 작성하면서 나의 생각을 한 번 정리해보고, 더 나은 방식을 고민해보도록 하자.