[Fixture Monkey] Ch 01.

Eunbi Lee·2025년 4월 14일

SeaVantage

목록 보기
1/11
post-thumbnail

Test Code 를 왜 작성해야 할까?

우선, Test Code (이하 테스트 코드) 에 대해 이야기 하기에 앞서 왜 Test Code 를 작성해야할까? 🤔

직접 테스트 코드를 작성하면서 느꼈던 점은 크게 다음과 같다.

  • 구현 시, 예상하지 못한 예외 케이스를 catch 할 수 있다.
  • 특정 상황에 대한 코드를 간편하게 구현하여 테스트할 수 있다.

특히 1번의 경우는 Fixture Monkey의 장점과 연관되어 있는 내용이라고 생각한다.

Test Code 작성 방법

그렇다면 테스트 코드는 어떻게 작성할 수 있을까?

또한 테스트용 객체(a.k.a 목 객체)는 어떻게 생성할 수 있을까?

나와 같은 경우는 아래와 같은 3단계를 거쳐서 작성했었다.

1.new 생성자를 통한 객체 생성
2. @Builder 를 통한 객체 생성
3. Fixture monkey 를 통한 객체 생성

✍️ new 생성자를 통해 직접 객체 생성

다음과 같은 도메인이 있다고 가정해보자.

public record Profile (
   String name,
   int age,
   String gender
)

이 경우에 new 연산자를 통해 간단히 테스트용 객체를 생성할 수 있다.

Profile profile = new Profile(
    "이은비",
     20,
    "여"
);

하지만, Profile 도메인 내부의 필드가 많아진다면?

public record Profile (
   String name,
   int age,
   String gender,
   int phoneNumber,
   String adress,
   int residentRegistrationNumber,
   ..
   (etc)
)

결국 new 연산자를 사용한다면 모든 필드에 대해 값을 빠짐없이 넣어줘야 한다.

Profile profile = new Profile(
    "이은비",
     20,
    "여",
    01012345678,
    "강남구",
    001101,
    ..
);

특히, 테스트용 객체를 생성하다보면 필수값이 아닌 필드들에 대해서 값을 할당해주는 건 필요성을 느끼기 어려운 부분이다.

따라서 도메인 내의 모든 필드가 중요하기에 빠짐없이 작성해야 한다면 new 연산자를 사용하겠지만, 아니라면 Optional 하게 객체를 작성하고 싶은 경우가 자주 있다.

이럴 경우, @Builder 를 통해 객체를 생성할 수 있다.

📝 @Builder 를 통한 객체 생성

최근까지 사용했던 방법이고, 많은 프로젝트에서 볼 수 있는 목 객체 생성 방법이다.

이 방법은 @Builder 어노테이션을 통해 간편하고, Optional 하게 필드에 대해 값을 할당할 수 있다.

다시 필드가 많은 버전의 Profile 도메인을 봐보자.

public record Profile (
   String name,
   int age,
   String gender,
   int phoneNumber,
   String adress,
   int residentRegistrationNumber,
   ..
   (etc)
)

@Builder 를 통해 객체를 생성한다면 다음과 같다.

Profile profile = Profile.builder()
                         .name("이은비")
                         .age(20)
                         .gender("여")
                         .residentRegistrationNumber(001101)
                         .build();

특히, 위와 같이 필수 필드에 대해서 쉽게 값을 선택적으로 할당시켜줄 수 있다.

하지만 이렇게 작성할 경우, 내가 예상한 시나리오에 대해서만 테스트를 하는 느낌을 지울 수 없다.

즉, 놓칠 수 있는 예외 케이스에 대해서는 고려하지 못한 채 테스트를 진행하여 catch 할 수 없다는 것이다.

또한, 반복적으로 테스트를 작성하다보면 종종 null 이면 안되는 필드에 값을 할당해주지 않아서 NPE가 터지는 상황을 피할 수 없다.

이런 저런 고민 끝에 요즘 사용하기 시작한 테스트용 객체 작성 방법은 Fixture Monkey 이다.

🐒 Fixture Monkey

Fixture Monkey 는 앞서 설명했던 단점들을 어느정도 해결해주는 방법이다.

특히 Fixture Monkey 에는 객체를 생성하는 방법이 여러 가지가 있는데, 주로 사용하는 방법은 giveMeBuilder() 이다.

사용 예시는 다음과 같다.

private final FixtureMonkey monkey = MonkeyBuilder.monkey(
            ConstructorPropertiesArbitraryIntrospector.INSTANCE);

먼저 사용 전에 위와 같이 의존성 주입을 진행한다.

그리고, 다음과 같이 사용할 수 있다.

String name = "이은비";
int age = 20;
int residentRegistrationNumber = 001101; 

Profile profile = monkey.giveMeBuilder(Profile.class)
                        .set("name", name)
                        .set("age", age)
                        .set("residentRegistrationNumber", residentRegistrationNumber)
                        .sample();

1️⃣ .giveMeBuilder() : 객체 생성을 진행할 클래스를 주입한다.
2️⃣ .set() : 값을 세팅할 필드를 "필드명, ${value} 형태로 작성한다.
3️⃣ .sample() : @Builder의 .build() 와 같이 객체 생성을 마무리한다.

또한, Fixture Monkey 특성 상 무작위로 값을 세팅 을 진행하기 때문에 null 까지 주입해준다.

따라서 특정 필드에 null 이 들어가면 안될 경우, .setNull() 을 통해 NPE 를 방지할 수 있다.

후기

즉 Fixture Monkey 를 직접 사용해보면서 통해서 Test Code를 작성하는 2가지 장점을 느낄 수 있었다.

이 밖에도, 여러 메서드를 통해 목 객체를 생성할 수 있는데 (ex. giveMeOne, .. ) 본 내용은 다음 포스팅부터 공식 Docs 와 함께 자세히 다뤄보자! 😉

profile
안녕하세요, 개발자 비비입니다.

3개의 댓글

comment-user-thumbnail
2025년 4월 14일

Good job

1개의 답글