반응형

dependency

maven
<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-core</artifactId>
    <version>2.1-groovy-3.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-spring</artifactId>
    <version>2.1-groovy-3.0</version>
    <scope>test</scope>
</dependency>
gradle
dependencies {
    ...
    testImplementation 'org.spockframework:spock-core:2.1-groovy-3.0'
    testImplementation 'org.spockframework:spock-spring:2.1-groovy-3.0'
}

Basic

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

class SpockBasicTest extends Specification {
    def "test1"() {
        given:
        def a = 5
        def b = 10

        when:
        def result = a + b

        then:
        result == 15
    }

    def "test2"() {
        def a = 5
        def b = 10

        def result = a + b

        expect:
        result == 15
    }

    def "test3"() {
        expect:
        a + b == result

        where:
        a | b | result
        1 | 2 | 3
        5 | 10 | 15
    }

    @Unroll // 메소드 이름에 지정된 템플릿에 따라 테스트 결과를 보여줌
    def "test4 [#a + #b = #result]"() {
        expect:
        a + b == result

        where:
        a | b | result
        1 | 2 | 3
        5 | 10 | 15
    }

    def "test5"() {
        when:
        throw new IllegalStateException("TEST")

        then:
        def e = thrown(IllegalStateException)
        e.message == "TEST"
    }

    def "test6"() {
        when:
        println "nothing"

        then:
        notThrown(NullPointerException)
    }
}

Fixture Methods

import spock.lang.Shared
import spock.lang.Specification

class SpockFixtureTest extends Specification {
    @Shared def value = "root"

    def setupSpec() {
        println "setupSpec - ${value}"
    }

    def cleanupSpec() {
        println "cleanupSpec - ${value}"
    }

    def setup() {
        println "setup - root"
    }

    def cleanup() {
        println "cleanup - root"
    }

    def "test1"() {
        setup:
        println "setup - test1"

        expect: true
    }

    def "test2"() {
        setup:
        println "setup - test2"

        expect: true
    }
}
  • 실행 결과
setupSpec - root
setup - root
setup - test1
cleanup - root
setup - root
setup - test2
cleanup - root
cleanupSpec - root

Mock

import spock.lang.Specification

class SpockMockTest extends Specification {
    def "test1"() {
        given:
        def mock = Mock(Calculator)

        when:
        def result = mock.add(1, 2)

        then:
        mock.add(_, _) >> 1000  // 파라미터에 상관 없이 1000을 반환
        result == 1000
    }

    def "test2"() {
        given:
        def mock = Mock(Calculator)

        when:
        def result = mock.add(1, 2)

        then:
        1 * mock.add(_, _) >> 1000  // 1번 호출했는지 확인
        result == 1000
    }

    static class Calculator {
        def add(def a, def b) {
            return a + b
        }
    }
}

Spring Test

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import spock.lang.Specification
import com.example.api.ApiService

@SpringBootTest
class SpockSpringTest extends Specification {
    @Autowired
    ApiService apiService

    def "apiService 요청 테스트"() {
        when:
        def list = apiService.getList()

        then:
        !list.isEmpty()
    }
}

Spring Controller Test

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

class UserControllerTest extends Specification {
    def userService = Mock(UserService)
    def mockMvc = MockMvcBuilders.standaloneSetup(new UserController(userService)).build()

    def "GET /api/users"() {
        given:
        def request = get('/api/users').param("id", id as String)

        when:
        mockMvc.perform(request).andExpect(result as ResultMatcher)

        then:
        serviceCall * userService.getUser(id) >> serviceReturn

        where:
        id     | serviceCall | serviceReturn    | result
        null   | 0           | _                | status().isBadRequest()
        ""     | 0           | _                | status().isBadRequest()
        "john" | 1           | new User("john") | status().isOk()
    }

    def "POST /api/users"() {
        given:
        def request = post('/api/users').contentType(MediaType.APPLICATION_JSON).content(requestBody as String)

        when:
        mockMvc.perform(request).andExpect(result as ResultMatcher)

        then:
        serviceCall * userService.addUser(_) >> serviceReturn

        where:
        requestBody                                              | serviceCall | serviceReturn                                          | result
        '{"id": "john"}'                                         | 0           | _                                                      | status().isBadRequest()
        '{"id": "john", "password": "1234"}'                     | 0           | _                                                      | status().isBadRequest()
        '{"id": "john", "password": "1234", "role": "ADMIIIIN"}' | 0           | _                                                      | status().isBadRequest()
        '{"id": "john", "password": "1234", "role": "ADMIN"}'    | 1           | new UserAddResult(UserAddResult.Status.EXISTS_ALREADY) | status().isConflict()
        '{"id": "john", "password": "1234", "role": "ADMIN"}'    | 1           | new UserAddResult(UserAddResult.Status.SUCCESS)        | status().isOk()
    }
}

IntelliJ에서 Spock 테스트 실행시 "Test events were not received"가 뜨면서 실행이 되지 않을 경우

  • IntelliJ 설정 변경
    • File > Settings > Build, Execution, Deployment > Build Tools > Gradle > Build and run
    • Build and run using : IntelliJ IDEA
    • Run tests using : IntelliJ IDEA
  • 프로젝트 clean 후 테스트 재실행
    gradle clean
    
반응형

'Development > Spring' 카테고리의 다른 글

[Spring] BeanFactory & ApplicationContext  (0) 2020.12.27
[Spring] Paging  (0) 2020.12.27
[Spring] FileDownload  (0) 2020.12.27
[Spring] Controller  (0) 2020.12.27
[Spring] Spring Boot 프로젝트 세팅  (0) 2020.12.27

+ Recent posts