Spring | Fixtue Monkey를 사용해서 테스트 코드 작성하기

바다·2024년 6월 13일
0

Spring

목록 보기
11/13
post-thumbnail

🐒 Fixture Monkey

공식 GitHub : https://github.com/naver/fixture-monkey
공식 문서 : https://naver.github.io/fixture-monkey/v1-0-0/docs/introduction/overview/

Fixture Monkey는 제어 가능한 임의 테스트 개체를 생성하도록 설계된 Java 및 Kotlin 라이브러리다

테스트를 하기 위해서는 테스트 객체가 필요한데, Fixture Monkey를 사용하면 이전에 사용했던 길고 긴 테스트 객체 생성에 대한 코드를 줄일 수 있다! Bean Validation에 대한 설정이 있다면, 해당 설정에 맞게 객체를 생성해주니 안정적으로 테스트를 진행할 수 있다


사용 방법

1. dependency

build.gradle에 dependency를 추가해준다

testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter:1.0.14")

2. 테스트 클래스 내에 작성 or MonkeyUtils 클래스 생성

테스트 클래스 내에 작성하는 경우

FixtureMonkey fixtureMonkey() {
	return FixtureMonkey.builder()
    		.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
			.build();
}

MonkeysUtils 클래스를 생성해서 사용하는 경우

package december.spring.studywithme.utils;

import com.navercorp.fixturemonkey.FixtureMonkey;
import com.navercorp.fixturemonkey.api.introspector.ConstructorPropertiesArbitraryIntrospector;

public abstract class MonkeyUtils {
	public static FixtureMonkey commonMonkey() {
		return FixtureMonkey.builder()
			.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
			.build();
	}
	
}

3. 테스트 코드에서 사용

@Test
@DisplayName("댓글 생성 테스트")
void 댓글생성() {
	//given
	Post post = MonkeyUtils.commonMonkey().giveMeOne(Post.class);
	User user = MonkeyUtils.commonMonkey().giveMeOne(User.class);
    String contents = "댓글 내용입니다.";
	
    //when
	Comment comment = Comment.builder()
    	.post(post)
		.user(user)
		.contents(contents)
		.build();
	    
 	//then
	assertThat(comment.getPost()).isEqualTo(post);
	assertThat(comment.getUser()).isEqualTo(user);
	assertThat(comment.getContents()).isEqualTo(contents);
}

기존의 테스트 코드였다면, Post와 User를 직접 생성해 주어야 하기 때문에 작성해야 하는 코드가 많았지만 Fixture Monkey를 사용해 단 두 줄로 테스트 객체를 만들 수 있다!

4. 더 자세한 사용 방법은...

위의 블로그들과 공식문서를 참고해보면 좋다!
(공식 문서가 그리 친절하진 않아서... 나도 머리를 박박 긁으면서 사용했다...)


왜 사용하나요?

1. 단순성

FixtureMonkey fixureMonkey = FixtureMonkey.builder()
	.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
    .build();

User user = fixtureMonkey.giveMeOne(User.class);
  • Fixture Monkey를 사용하면 테스트 객체 생성이 매우 쉬워진다.
  • 단 한 줄의 코드만으로 원하는 모든 종류의 테스트 객체를 손쉽게 생성할 수 있다.
  • 테스트의 given 구간의 코드를 단순화하여 테스트를 더 빠르고 쉽게 작성할 수 있다.

2. 재사용성

ArbitarayBuilder<User> actual = fixtureMonkey.giveMeBuilder(User.class)
	.set("id", 10L)
    .set("name", "name");
  • 여러 테스트에서 인스턴스 구성을 재사용할 수 있기 때문에, 시간과 노력을 절약할 수 있다.
  • 복잡한 내용은 빌더 내에서 한 번만 정의하면 되고 이후에는 재사용을 통해 같은 인스턴스를 얻을 수 있다.

3. 무작위성

ArbitaryBuilder<User> actual = fixtureMonkey.giveMeBuilder(User.class);

then(actual.sample()).isNotEqualTo(actual.sample());
  • Fixture Monkey는 임의의 값으로 테스트 객체를 생성해서 테스트를 더욱 동적으로 만들어 준다.
  • 편협한 시각으로 알아내지 못했던 엣지 케이스에 대해 발견할 수 있다.

4. 다양성

// inheritance
class Foo {
  String foo;
}

class Bar extends Foo {
    String bar;
}

Foo foo = FixtureMonkey.create().giveMeOne(Foo.class);
Bar bar = FixtureMonkey.create().giveMeone(Bar.class);

// circular-reference
class Foo {
    String value;

    Foo foo;
}

Foo foo = FixtureMonkey.create().giveMeOne(Foo.class);

// anonymous objects
interface Foo {
    Bar getBar();
}

class Bar {
    String value;
}

Foo foo = FixtureMonkey.create().giveMeOne(Foo.class);
  • Fixture Monkey로 상상하는 모든 객체를 만들 수 있다.
  • List, 중첩된 컬렉션, 열거형, 일반 유형 같은 기본 객체 생성을 지원한다

🍌 결론

  • 공식문서를 보고 차근차근 적용해볼 마음이 있다면 추천!
  • 다양한 커스텀을 통한 테스트 객체 생성이 가능하다!
  • 테스트 코드를 확! 죽일 수 있다
profile
ᴘʜɪʟɪᴘᴘɪᴀɴs 3:14

1개의 댓글

comment-user-thumbnail
2024년 6월 14일

MonkeyUtils를 사용하는 경우는 간단하게 어떤 경우에 용이한지 여쭤볼 수 있을까요? 저같은 코린이는 ConstructorPropertiesArbitraryIntrospector(주어진 생성자를 통해서 객체를 생성할 때 사용) 이게 주된 이유인가 싶습니다!

답글 달기