인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

ykm8864님의 프로필 이미지
ykm8864

작성한 질문수

Practical Testing: 실용적인 테스트 가이드

테스트 환경의 독립성을 보장하자

테스트 given절 작성 시, "팩토리 메서드를 통한 생성 지양" 관련 문의

작성

·

61

0

  • 학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!

  • 먼저 유사한 질문이 있었는지 검색해 보세요.

  • 서로 예의를 지키며 존중하는 문화를 만들어가요.

     

 강의에서 테스트 given절에서 팩토리 메서드를 통한 객체 생성은 어떠한 의도가 들어갈 수 있으므로 지양하라고 하셨습니다. 관련하여 질문이 있습니다.

 

예를 들어 다음과 같은 팩토리 메서드가 있다고 하면,

public class Coffee {

private String type;

private int size;

public Coffee(String type, int size) {

this.type = type;

this.size = size;

}

}

public class SeasonalCoffeeFactory {

public static Coffee createCoffee(String season) {

switch (season.toLowerCase()) {

case "summer":

return new Coffee("Iced Coffee", 50);

case "winter":

return new Coffee("Hot Coffee", 30);

case "spring":

return new Coffee("Latte", 40);

case "fall":

return new Coffee("Pumpkin Spice Latte", 45);

default:

throw new IllegalArgumentException("Unknown season: " + season);

}

}

}



여름 시즌 커피에 대한 테스트 코드는 다음과 같을 겁니다.

@Test

public void testCreateSummerCoffee() {

Coffee coffee = SeasonalCoffeeFactory.createCoffee("summer");

assertEquals("Iced Coffee", coffee.getType());

assertEquals(50, coffee.getSize());

}



이때 테스트 코드는 시즌에 맞는 커피 메뉴를 given절에 생성한 후 타입 일치여부만 판단하면 됩니다.

하지만 이 부분을 팩토리 메서드로 작성하지 않게되면
커피를 생성함에 있어
if ("summer".equalsIgnoreCase(season)) {

coffee = new Coffee("Iced Coffee", 50);

} else if...

와 같은 부분이 테스트 코드의 given절에 들어가야하지 않나 싶습니다. 물론 이런 부분에 대해서 if라는 논리구조가 들어갔으니 한번 더 테스트 코드 메서드가 분리되어야하는건가 싶기도 한데 확신이 잘 안 서서 질문 드리고 싶습니다.

긴 글 읽어주셔서 감사합니다.

답변 2

0

박우빈님의 프로필 이미지
박우빈
지식공유자

안녕하세요, ykm8864 님!

먼저 질문 드리고 싶은 것은, 현재 테스트하려는 대상(when절)이 무엇인가요?

  • SeasonalCoffeeFactory.createCoffee() 가 테스트 대상이라면,

    • Coffee coffee = SeasonalCoffeeFactory.createCoffee("summer"); 로 여름 시즌에 대한 커피가 잘 생성되었는지를 검증하시면 됩니다.

  • 검증하려는 대상이 Factory.createCoffee()가 아니라 Coffee의 다른 메서드이거나, 혹은 Coffee를 사용하는 다른 객체라면,

    • Coffee라는 fixture를 생성할 때 특정 상황에 맞는 Coffee를 다이렉트로 생성하라는 의미입니다.

    • Factory를 통해 생성한 Coffee는, 만약 Factory의 내부 로직이 변경되었을 경우 전혀 상관 없는 이 곳 메서드까지 영향을 줄 수 있거든요.

정리하면, 검증 대상인 when절에서 팩토리 메서드를 사용하지 말라는 것이 아니라, given절의 fixture를 만들 때 그러지 않기를 이야기하는 것입니다.

도움이 되셨기를 바랍니다.
감사합니다. 🙂

0

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

질문해주신 ‘팩토리 메서드를 통한 객체 생성 지양’이라는 원칙에 대해 설명드리겠습니다. 강의에서는 새로운 인스턴스를 생성할 때 팩토리 메서드 대신 생성자나 빌더 패턴을 사용하는 것을 권장했죠. 이는 팩토리 메서드가 추가적인 의도를 내포하게 되어 테스트의 독립성과 순수성을 저해할 수 있기 때문입니다.

여름 시즌 커피 예시로 들면, 팩토리 메서드를 사용하면 커피 타입과 크기가 시즌별로 결정되는 로직이 감춰집니다. 이를 테스트할 때는, 단순히 팩토리 메서드를 호출한 결과만 확인하는 것이 아니라, 이러한 로직이 기대대로 작동하는지도 검증해야 합니다.

테스트 코드를 작성할 때 if문 같은 조건문을 걱정하시는 것 같습니다. 하지만 중요한 것은, 테스트되고 있는 기능이 무엇인지 명확히 하고, 그 기능에 대한 기대 결과를 확인하는 것입니다. 팩토리 메서드 내에서 선언된 로직이 복잡하다면 해당 로직에 대한 별도의 단위 테스트가 필요할 수 있습니다.

수강생님이 말씀하셨듯이, 조건부 로직이 길어질 경우 별도의 테스트 메서드나 테스트 클래스를 도입하여 이를 분리할 수 있습니다. 이는 테스트 코드의 가독성 및 유지보수성을 높이는 데 도움이 됩니다.

관련된 강의 게시물로는 팩토리메서드를 지양하고 생성자 혹은 Builder 패턴을 쓰라는 말씀에 관하여라는 질문 게시물이 있습니다. 여기에서 팩토리 메서드의 사용과 관련해 생성자나 빌더 패턴을 사용하는 이유에 대해 자세히 다루고 있습니다.

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

ykm8864님의 프로필 이미지
ykm8864

작성한 질문수

질문하기