Kotlin

private 함수를 테스트하고 싶을때

mayleaf 2024. 3. 20. 01:13

이 글을 쓰는 목적

이 글은 private 함수를 테스트하고 싶은 분을 위해 작성된 코드입니다.

이 글에서 다루는 내용

이 글을 테스트 프레임워크를 통해서 private 함수를 테스트하는 내용이 아닙니다. private 함수를 public으로 바꾸기는 애매하고, private 상태로 테스트하자니 테스트 픽스쳐를 다수 만들어서 코드를 짜야할 것 같은 상황에 있는 사람. 그리고 그런 상황으로 인해서 미래 코드의 순 서가 변경되거나 테스트의 순서가 변경될까봐 다른 방법을 찾아보고 있는 분을 위해서 작성하는 글입니다.

 

본문

우선 이 글을 보고 계신 분이라면 이미 private 함수를 public으로 오픈해보는 방법에 대해서는 고민해보셨을 것 같습니다.

하지만 오픈하지 않으시는 이유가 있다면 해당 클래스에서 은닉, 캡슐화해둔 것이 클래스 밖으로 보여주기 싫기 때문일 것이라고 생각합니다.

예를 들어서 상품을 저장하는 로직이 productService.save에 구현이 되어있는데, 상품의 정보를 검증하기 위해서 validation을 해주는 코드가 service에 있다고 해봅시다. 그러면 검증해주는 로직이 사진 정보나, 상품 유형이나, 등록자나, 혹은 재고 수라던가 하는 부분들을 검증해주는 로직들을 함수들로 빼둘 것입니다. 그런데, 이런 함수들을 오픈한다면 productService.validateStock()과 같은 함수들이 외부로 노출되고 이는 외부에서 봤을때 productService가 가지고 있는 관심사에서 벗어났다는 생각이 들것입니다.

적어도 저라면 이게 뭔데 밖에서 쓰라고 열어둔걸까? 하고 fuzzySearch로 타고 들어갈 것 같습니다. 

 

그렇다면 테스트 프레임워크도 사용하지 않고, public으로 오픈도 하지 않는다면 어떻게 테스트 하지? 라는 생각이 들 수 있습니다.

우리가 이런 고민을 하는 이유는 딱 하나입니다. 위에서 언급한 로직들이 productService에서 관심이 있어할만한 코드가 아니기 때문입니다. productService를 주입받는 코드를 작성하는 사람은 아마 상품의 저장이나, 조회, 수정등의 기능사용하기 위해서 주입받는 것이지, 재고수를 검증하는 방법따위는 관심이 아닐 것입니다.

 

이에 대한 대답은 관심이 있어할 만한 코드의 스코프로 이동시켜야한다는 것입니다.

우리는 이 함수들을 관심이 있을 법한 스코프로 움직이면 됩니다. 예를 들어 validateStock이라는 함수가 ProductStockValidator라는 클래스 안에 구현되어있다면 어떤 생각이 드시나요? ProductStockValidator.validateStock

당연히 public으로 오픈되어있어야하고, 이 검증클래스를 불러서 상품의 재고수를 검증하고 싶어질 것입니다.

 

이렇게 되면 검증로직도 단위 테스트를 작성할 수 있고, 나중에 다른 검증로직이 아무리 바뀌어도 무결하게 코드의 안정성이 증명되는 코드를 작성할 수 있을 것입니다.

 

결론

테스트코드 짤때, 이 함수 public으로 오픈해도 되나 ? 라는 생각이 든다면, 잘못된 위치에 있는 코드이므로 클래스를 분리하거나, 적절한 클래스의 함수로 변경하면됩니다.