• 티스토리 홈
  • 프로필사진
    아몬드맛빼빼로
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
아몬드맛빼빼로
  • 프로필사진
    아몬드맛빼빼로
    • 분류 전체보기 (46)
      • Java (8)
      • C (3)
      • Springboot (7)
      • Kotlin (2)
      • 회고 (5)
      • Backend (13)
      • 기타 (5)
      • DevOps (3)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
# Home
# 공지사항
#
# 태그
# 검색결과
# 방명록
  • [Backend] 네이버가 오픈소스를..? Fixture Monkey
    2025년 08월 24일
    • 아몬드맛빼빼로
    • 작성자
    • 2025.08.24.:54
    반응형

    문제상황

    교내 입학지원시스템 HelloGSM의 테스트 코드 작성 중 문제가 한 가지 발생하였다. 입학지원시스템이다 보니 입학원서를 작성하게 되고 이 입학원서가 저장해야 하는 데이터가 워낙 방대하다 보니 이것을 테스트하는 테스트 코드에서 Mock 객체를 생성하는 부분이 굉장히 커지게 되었다. 이를 해결하기 위한 방안을 찾아보던 중 네이버에서 개발한 오픈소스 라이브러리 Fixture Monkey를 알게 되었다.

    이게 뭐에요

    간단히 이야기하자면 테스트 객체 생성을 간단하게 처리해 주는 라이브러리이다.

    아래와 같이 단 한 줄로 객체 생성이 가능하다.

    Oneseo oneseo = fixtureMonkey.giveMeOne(Oneseo.class);

    이를 통하여 객체 생성을 실제 코드에 대한 의존성 없이 수행할 수 있다

     

    또한 빌더 패턴이 적용되지 않은 객체도 인스턴스의 구성을 재사용할 수 있도록 빌더 패턴의 형식으로 생성하고 이를 계속 재사용할 수 있다.

    ArbitraryBuilder<Oneseo> actual = fixtureMonkey.giveMeBuilder(Oneseo.class)
        .set("OneseoId", 1L)
        .set("OneseoSubmitCode", "A-1");

     

    개인적으로 해당 라이브러리의 핵심적인 기능이라 생각되는데 무작위 데이터 바인딩 기능이다. 일반적인 테스트 코드 작성방식에선 정적 값을 바인딩하기에 잠재적인 예외 케이스가 존재할 수 있으나 무작위 값을 바인딩하여 테스트하는 방법으로 조금 더 안전한 테스트를 할 수 있다.

    ArbitraryBuilder<Oneseo> actual = fixtureMonkey.giveMeBuilder(Oneseo.class);
    
    then(actual.sample()).isNotEqualTo(actual.sample());
    더보기

    주의점

     

    필드에 @NotNull 어노테이션이 적용되어 있지 않다면 해당 필드에 null을 바인딩할 수도 있는데 비즈니스 로직에서 해당 필드에 null이 바인딩되는 것을 허용하지 않는다면 NPE가 발생할 수 있다. 해당 라이브러리 사용 시 @NotNull 어노테이션 적용여부를 확실히 점검해야 한다.

    사용해 보기

    1. 종속성 추가

    testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter:1.1.14") // 2025년8월24일 기준 최신버전

    Gradle 기준 해당 종속성만 추가해 주면 사용할 수 있다

    2. 테스트 코드 작성하기

    예시로 사용할 객체는 다음과 같다.

    @AllArgsConstructor
    public class Oneseo {
    	private Long oneseoId;
        private String oneseoSubmitCode;
    }

    그리고 객체가 Null이 아님을 검증하는 간단한 테스트 코드를 만들어본다면

    @Test
    void test() {
        // given
        FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
            .objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
            .build();
    
        // when
        Oneseo actual = fixtureMonkey.giveMeOne(Oneseo.class);
    
        // then
        then(actual).isNotNull();
    }

    다음과 같이 만들 수 있다.

    더보기

    주의점

     

    Fixture Monkey는 내부적으로 Java Beans 규약을 따르기 때문에 Lombok의 @AllArgsConstructor를 사용하여 생성자를 이용할 경우 ConstructorPropertiesArbitraryIntrospector를 사용하거나 lombok.config 파일을 생성하여 lombok.anyConstructor.addConstructorProperties=true를 설정해야 한다.

    3. 객체 필드 값 커스텀하기

    객체의 각 필드에 정적인 값을 할당하고 싶다면 giveMeBuilder()를 사용 후 set()을 사용하여 값을 설정할 수 있다.

    @Test
    void test() {
        // given
        FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
            .objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
            .build();
    
        // when
        Oneseo actual = fixtureMonkey.giveMeBuilder(Oneseo.class)
            .set("oneseoId", 1L)
            .sample();
    
        // then
        then(actual.getOneseoId).isEqualTo(1L);
    }

    Introspector

    Introspector란 객체가 생성되는 방법을 의미하며 4가지를 지원한다.

    1. BeanArbitraryIntrospector

    어떤 Introspector도 지정하지 않으면 설정되는 기본 설정값으로 Java Reflection과 설정자를 사용해서 객체를 생성한다.

    2. ConstructorPropertiesArbitraryIntrospector

    주어진 생성자를 통해서 객체를 생성할 때 사용한다.

    3. FieldReflectionArbitraryIntrospector

    Java Reflection만으로 객체를 생성할 때 사용한다.

    4. BuilderArbitraryIntrospector

    Builder 패턴을 사용하여 객체를 생성할 때 사용한다.

    5. FailoverArbitraryIntrospector

    테스트 대상이 다양한 객체를 내부적으로 가지고 있어 생성 방법이 여러 가지 필요하다면 사용할 수 있는 것으로 여러 Introspector를 제공할 수 있다.

    FixtureMonkey sut = FixtureMonkey.builder()
        .objectIntrospector(new FailoverIntrospector(
            Arrays.asList(
                FieldReflectionArbitraryIntrospector.INSTANCE,
                ConstructorPropertiesArbitraryIntrospector.INSTANCE
            )
        ))
        .build();

    마무리

    사실 공개된 지 2년밖에 되지 않은 라이브러리이고, 네이버나 오픈소스 커뮤니티에서 크게 밀어주는 프로젝트는 아니다 보니 아쉬운 점이 없는 것은 아니다. 커스텀 검증기를 완전히 지원하기 어렵고, Jakarta EE의 최신 제약 조건 API를 온전히 지원하지 않는 점도 한계로 꼽을 수 있다. 그럼에도 불구하고 Kotlin과 Java 동시 지원, 다양한 테스트 엔진(Kotest, JUnit, Jqwik 등) 활용 가능성은 충분히 진취적이다. 이러한 라이브러리를 알고 있다는 것만으로도 추후 프로젝트 진행 시 선택지를 하나 더 확보할 수 있다는 점에서 긍정적인 의미가 있다.

    저작자표시 비영리 변경금지 (새창열림)

    'Backend' 카테고리의 다른 글

    [Backend] pt-online-schema-change  (0) 2025.09.04
    [Backend] EDA  (0) 2025.07.15
    [Backend] OAuth와 JWT  (0) 2025.06.08
    [Backend] MQ  (0) 2025.05.05
    [Backend] CloudWatch 이론  (0) 2025.04.29
    다음글
    다음 글이 없습니다.
    이전글
    이전 글이 없습니다.
    댓글
조회된 결과가 없습니다.
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
목차
표시할 목차가 없습니다.
    • 안녕하세요
    • 감사해요
    • 잘있어요

    티스토리툴바