easyRandom으로 테스트코드를 편하게 작성하기
테스트 코드를 작성할 때 불편한 것들
테스트 코드를 작성할 때 흔히 겪는 불편함은 무엇일까요?
의존성을 mocking 하거나 stubbing 하는 작업, 테스트 데이터 관리는 항상 골치 아픈 부분입니다.
이러한 작업은 실제 테스트를 수행하기 위해 많은 시간과 노력을 요구합니다.
예시 - Request의 필드가 100개라면
data class TooManyField(
val col1: String,
val col2: String,
val col3: String,
// ...
val col100: String,
)
1. 100개의 필드를 일일이 작성하고 관리하는 것은 번거롭고 시간이 많이 걸립니다.
2. 테스트 코드의 가독성이 떨어져 이해하기 어려워집니다.
위의 예시는 극단적인 케이스이고 필드가 100개라는 것은 해당 클래스가 너무 많은 역할을 하고 있다는 신호일 수도 있습니다.
테스트를 위해서 100개의 필드가 모두 세팅이 필요하다면 모두 세팅해야겠지만 대부분 Request의 특정 필드에만 필요한 경우가 많았습니다.
불편함을 해결할 수 있는 방법
easyRandom, FixtureMonkey 등의 라이브러리를 활용하거나 언어의 특성을 활용하여 미리 테스트 데이터를 세팅해 둘 수 있습니다.
Kotlin 언어의 특성을 활용하여 테스트 데이터 세팅
object TestHelper{
fun tooManyFieldFixture(
col1: String = "col1",
col2: String = "col2",
col3: String = "col3",
col100: String = "col100",
): TooManyField{
return TooManyField(
col1 = col1,
col2 = col2,
col3 = col3,
col100 = col100,
)
}
}
@Test
fun `TestHelper 활용`(){
val sut = TestHelper.tooManyFieldFixture(col3 = "테스트하고 싶은것 override")
sut.col3 shouleBe "테스트하고 싶은것 override"
}
위의 예시처럼 Kotlin 언어의 특성을 활용하여 테스트 데이터 세팅해 둘 수 있지만 실제 클래스가 수정될 때 TestHelper 클래스도 같이 유지보수해야 합니다.
easyRandom 라이브러리를 활용하여 테스트 데이터 세팅
EasyRandom을 사용하면 객체의 모든 필드를 자동으로 무작위 값으로 채울 수 있습니다.
이는 특히 필드가 많거나 복잡한 객체를 테스트할 때 매우 유용합니다.
gradle
implementation ("org.jeasy:easy-random-core:5.0.0")
테스트코드-활용
@Test
fun `easyRandom 활용`(){
val easyRandom = EasyRandom()
val sut: TooManyField = easyRandom.nextObject(TooManyField::class.java)
.copy(col3 = "테스트하고 싶은것 override")
assertEquals(sut.col3, "테스트하고 싶은것 override")
}
Kotlin의 data class의 copy() 함수를 사용하여 객체를 복사하면 객체의 일부 속성은 변경하지 않고 나머지는 그대로 유지하면서 변경할 수 있습니다.
조금 더 편하게 easyRandom 활용해 보기
val EASY_RANDOM = EasyRandomParameters()
.collectionSizeRange(2,3)
.randomize(Long::class.java, LongRangeRandomizer(1, 10000)) // Long 타입에 대하여 1~10000으로 범위 제약
.run { EasyRandom(this) }
inline fun <reified T: Any> easyRandom(): T = EASY_RANDOM.nextObject(T::class.java)
테스트객체를 생성할 때마다 EasyRandom 객체를 생성해주어야 합니다.
또한 EasyRandom에는 EasyRandomParameters를 활용하여 다양한 옵션을 부여할 수 있습니다.
collectionSizeRange로 컬렉션을 크기 범위를 제약하거나 randomize 메서드를 활용하여 특정 타입에 대한 랜덤값을 제어할 수 있습니다.
사용할 때는 랜덤으로 만들고 싶은 객체의 타입을 넘겨주면 됩니다
@Test
fun `조금 더 편하게 easyRandom 활용`(){
val sut = easyRandom<TooManyField>()
.copy(col3 = "테스트하고 싶은것 override")
assertEquals(sut.col3, "테스트하고 싶은것 override")
}
FixtureMonkey와 easyRandom
테스트의 편의성을 위해서 easyRandom 이외에도 네이버에서 만든 FixtureMonkey를 활용해 볼 수도 있습니다.
Github기준의 Star의 개수로는 easyRandom이 1.6k FixtureMonkey는 500개 정도이지만 easyRandom은 2020년부터 maintenance mode(유지보수 모드)입니다.
easyRandom 이외에 FixtureMonkey도 좋은 선택지가 될 수 있을 것 같습니다.
참고자료
https://kotlinlang.org/docs/data-classes.html
https://www.baeldung.com/java-easy-random
https://github.com/j-easy/easy-random