프로젝트를 마친 후 테스트코드를 보던 중 지저분한 FixtureFactory
클래스를 정리하고 싶은 마음이 생겼습니다. 길어진 given 단계가 생겨 코드의 가독성이 떨어져 이를 위해 생성한 클래스였지만 클래스의 크기가 점점 커지고 읽기 어려워지는 문제가 있었습니다.
만약 클래스의 개수가 늘어나게 되면 fixture 생성 메서드는 계속 늘어날 것입니다.
이런 테스트 데이터를 만드는 번거로운 작업을 줄이기 위해 사용할 수 있는 것이 Fixture Monkey 입니다.
Fixture Monkey는 네이버페이 팀에서 만든 오픈소스 프로젝트입니다.
Fixture Monkey는 아래와 같은 두 가지 목표를 가지고 있습니다.
기본적으로 Java/JUnit5를 지원합니다. 필요에 따라 서드파티 모듈을 추가하여 사용해야 하는 점을 유의합시다.
이것 말고도 아래와 같은 것들이 더 있습니다.
프로젝트에서는 Gradle
을 사용했기 때문에 아래와 같이 의존성을 추가합니다.
testImplementation 'com.navercorp.fixturemonkey:fixture-monkey-starter:0.5.0'
Java를 사용해서 개발을 하고 있기 때문에 아래와 같이 FixtureMonkey 인스턴스를 생성합니다.
FixtureMonkey sut = FixtureMonkey.builder()
.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
.build();
이를 사용하기 위해서는 아래 조건 중 하나만 만족하면 됩니다.
record
타입입니다.lombok.anyConstructor.addConstructorProperties=true
옵션을 추가합니다.물론 간단하게 다음과 같이 생성할 수도 있습니다.
FixtureMonkey sut = FixtureMonkey.create();
이때 기본 생성 전략은 BeanArbitraryIntrospector
이기 때문에 아래와 같은 필요조건이 존재합니다.
2번 조건에서 테스트하려는 모든 클래스에 세터를 적용하는 것은 좋지 않다고 생각했습니다. 왜냐하면 테스트코드를 위한 도메인 변경은 적절치 않다고 생각하고 도메인의 모든 필드에 세터를 열어주는 것은 변경가능성이 많이 생겨버리기 때문입니다.
따라서 위의 ConstructorPropertiesArbitraryIntrospector.INSTANCE
를 택하기로 했습니다.
먼저 FixtureMonkey
인스턴스를 생성합니다.
private static final FixtureMonkey sut = FixtureMonkey.builder()
.defaultNotNull(Boolean.TRUE)
.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
.build();
ItemDetailsResponse response = sut.giveMeOne(ItemDetailsResponse.class);
List<CategoryResponse> response = sut.giveMe(CategoryResponse.class, 3);
OrderReceiptRequest orderReceiptRequest = sut.giveMeBuilder(OrderReceiptRequest.class)
.set("orders", new OrdersRequest(1, 1))
.sample();
sut.giveMeBuilder(ItemDetails.class)
.set("options[*]", Arbitraries.strings())
.sample();
sut.giveMeBuilder(ItemDetails.class)
.set("options[n]", Arbitraries.strings())
.sample();
FixtureMonkey를 적용해 따로 FixtureFactory
클래스를 두어 100라인에 달하던 fixture를 생성하는 코드를 모두 제거하게 되었습니다.
또한 클래스의 필드, 생성자 등이 변경되어도 메서드 하나하나를 수정할 필요가 없게 되어 테스트 로직에 집중할 수 있게 되었습니다.
위에서 소개해 드린 내용말고도 공식문서를 보면 유용한 내용이 많습니다.
그런데 약간 불친절한 것 같습니다..