Spock
Spock 란 Groovy 언어를 이용하여 테스트 코드를 작성할 수 있는 프레임워크이며 JUnit 과 비교하여 코드를 더 간결하게 작성 가능하다.
Groovy 언어는 동적 타입 프로그래밍 언어로 JVM 위에서 동작하며 Java문법과 유사하다.
테스트 메서드 이름을 문자열로 작성할 수 있으며(띄어쓰기가 가능하다.) given, when, then 코드 블록을 명확히 구분할 수 있다.
Junit의 경우 주석으로 블록을 구분했었고, 메소드 이름 또한 제약사항이 많이 존재한다.
plugins {
id 'java'
id 'org.springframework.boot' version '2.6.11'
id 'io.spring.dependency-management' version '1.0.13.RELEASE'
id 'groovy'
}
dependencies {
// spock
testImplementation('org.spockframework:spock-core:2.3-groovy-3.0')
testImplementation('org.spockframework:spock-spring:2.3-groovy-3.0') // Spring과 같이 사용하기 위함
// 런타임에 클래스 기반 spock mock을 만들기 위함
testImplementation('net.bytebuddy:byte-buddy:1.12.19')
}
테스트 클래스는 Groovy 클래스로 생성하고, Specification 클래스를 상속 받는다.
feature(테스트 메서드는) def를 이용하여 함수로 선언하며, 하나 이상 블록이 존재해야 한다.
given 블록 : 테스트에 필요한 값을 준비한다.
when 블록 : 테스트할 코드를 실행한다.
then 블록 : when과 함께 사용하며 예외 및 결과 값을 검증한다.
expect 블록 : then과 같으며 when을 필요로 하지 않기 때문에 간단한 테스트 및 where와 같이 사용된다.
where 블록 : 데이터가 다르고 로직이 동일한 경우 동일한 테스트에 대한 중복 코드 제거 가능하다.
JUnit에서 제공하는 주요 요소들은 모두 Spock에서 제공하고 있다.
class DivideUtils {
public static int divide(int input, int divide) {
if (divide == 0) {
throw new ArithmeticException("0으로 나눌 수 없다.");
}
return input/ divide;
}
}
class DivideUtilsTest extend Specification {
def "0으로 나눌 때 에러가 발생하는지 테스트"() {
given:
int input = 5
when:
DivideUtils.divid(input, 0)
then:
def e = thrown(ArithmeticException.class)
e.message == "0으로 나눌 수 없다."
}
}
where | 로 구분한 Data Table로 생성이 가능하며 파라미터, 결과값을 보기 좋게 구분 가능하다.
def "convertAddressToGeo according to multiple parameters() {
expect:
result == addressConverterService.convertAddressToGeospatialData(address).isPresent()
where:
address | result
"서울 특별시 서초구 잠원동" | true
"서울 특별시 서초구 잠원동 8" | true
"서울 특별시 서초구 반포동" | true
"서울 특별시 서초구 잘못된 주소" | false
"서울 특별시 서초구 251-123411" | false
"" | false
}