테스트/Spock

Spock 프레임워크의 @Unroll과 where 절 사용하기

Griotold 2025. 3. 4. 17:29

 

1. 문제 상황

 

최근 프로젝트에서 Role 이라는 Enum 클래스를 만들면서 of 메서드를 추가하게 되었다. 

이 메서드는 문자열 입력값을 받아 Enum 값을 반환하는 역할을 한다.

 

package com.griotold.auth.domain.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum Role {
    MASTER("ROLE_MASTER"),
    HUB("ROLE_HUB"),
    DELIVERY("ROLE_DELIVERY"),
    COMPANY("ROLE_COMPANY");

    private final String role;

    public static Role of(String request) {
        if (request == null) {
            return null;
        }

        return switch (request.toUpperCase()) {
            case "MASTER" -> MASTER;
            case "HUB" -> HUB;
            case "DELIVERY" -> DELIVERY;
            case "COMPANY" -> COMPANY;
            default -> null;
        };
    }
}

 

 

여기서 핵심은 대소문자 구분 없이 문자열이 들어와도 올바른 Role Enum 값을 반환해야 한다는 점이었다.

현 프로젝트는 Spock 이라는 테스트 프레임워크를 사용하고 있다.

 

2. 테스트 코드 작성

 

of 메서드가 올바르게 동작하는지 테스트 코드를 작성해보자.

특히, 여러 입력값을 한 번에 테스트하기 위해 where: 절을 사용했다.

 

package com.griotold.auth.domain.enums

import spock.lang.Specification
import spock.lang.Unroll

class RoleTest extends Specification {

    @Unroll
    def "of 메서드가 대소문자 상관없이 올바른 Role을 반환해야 한다"() {
        expect:
        Role.of(input) == expectedRole

        where:
        input      || expectedRole
        "MASTER"   || Role.MASTER
        "master"   || Role.MASTER
        "MaStEr"   || Role.MASTER
        "HUB"      || Role.HUB
        "hub"      || Role.HUB
        "Hub"      || Role.HUB
        "DELIVERY" || Role.DELIVERY
        "delivery" || Role.DELIVERY
        "COMPANY"  || Role.COMPANY
        "company"  || Role.COMPANY
    }

    @Unroll
    def "of 메서드가 유효하지 않은 입력값에 대해 null을 반환해야 한다"() {
        expect:
        Role.of(input) == null

        where:
        input << [null, "", "INVALID", "123", "ROLE_MASTER"]
    }
}

 

3. @Unroll의 역할

테스트 코드를 작성하면서 @Unroll 어노테이션을 처음 접했다.

처음에는 없어도 테스트가 정상 실행되었기 때문에 큰 차이를 느끼지 못했다.

하지만 @Unroll을 사용하면 테스트 실행 결과에서 개별 입력값이 명확하게 출력되며,

실패 시 어떤 값에서 문제가 발생했는지 바로 확인할 수 있다.

예를 들어, @Unroll을 적용한 테스트 실행 결과는 다음과 같다.

 

4. @Unroll 을 활용해 가독성 높이기

 

@Unroll에 문자열을 추가하면, Test Results 의 가독성을 높일 수 있다.

 

package com.griotold.auth.domain.enums

import spock.lang.Specification
import spock.lang.Unroll

class RoleTest extends Specification {
    
    // 문자열 추가!
    @Unroll("입력값 #input 일 때, 예상 결과는 #expectedRole 이어야 한다")
    def "of 메서드가 대소문자 상관없이 올바른 Role을 반환해야 한다"() {
        expect:
        Role.of(input) == expectedRole

        where:
        input      || expectedRole
        "MASTER"   || Role.MASTER
        "master"   || Role.MASTER
        "MaStEr"   || Role.MASTER
        "HUB"      || Role.HUB
        "hub"      || Role.HUB
        "Hub"      || Role.HUB
        "DELIVERY" || Role.DELIVERY
        "delivery" || Role.DELIVERY
        "COMPANY"  || Role.COMPANY
        "company"  || Role.COMPANY
    }
    
    // 문자열 추가!
    @Unroll("입력값 #input 일 때, 예상 결과는 null 이어야 한다")
    def "of 메서드가 유효하지 않은 입력값에 대해 null을 반환해야 한다"() {
        expect:
        Role.of(input) == null

        where:
        input << [null, "", "INVALID", "123", "ROLE_MASTER"]
    }
}

 

위 처럼, 문자열을 추가하면 좀 더 가독성을 높일 수 있다.

 

4. 결론

 

Spock에서 where 절을 활용하면 여러 테스트 케이스를 깔끔하게 작성할 수 있고,

@Unroll을 사용하면 실행 결과를 더욱 직관적으로 확인할 수 있다.

앞으로도 데이터 기반 테스트를 작성할 때 적극 활용할 계획이다.

 

References

 

https://blog.leocat.kr/notes/2019/05/01/spock-unroll-the-parameterized-tests#google_vignette