testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4' testCompile group: 'cglib', name: 'cglib-nodep', version: '3.2.4' // Class Mocking 할 때 필요.
// 일반적인 테스트 def "Feature Method name"() { :given "생략가능" // 테스트용 데이터 초기화 :when // 테스트 대상 코드를 실행하고 실행 결과를 변수 등에 저장 :then // 테스트 결과에 대한 검증. // 각 줄은 boolean 결과를 내는 Statement 로 작성한다. // 만약 한 줄의 코드가 boolean statement가 아니고 복잡한 구문일 경우에는 // 그 안의 assert boolean 구문에 'assert somebooleanexpression' 형태로 assert를 붙여야한다. } // Data Driven 테스트 def "Feature method name #a - #b = #c"(변수 a, 변수 b, 변수 c) { expect: // 각 데이터 변수로 테스트 수행 where: "각 데이터 변수 설정" a | b || c 1 | 2 || 3 4 | 5 || 6 }
// Argument capture def extern = null 1 * mock.foo( { extern = it; it.size() > 0 }) // 1.2 방식 1 * mock.foo( { it.size() > 0 }) >> { extern = it[0] } // 1.3 방식
// an interface with two methods: exists(user), add(user) def userService = Mock(UserService) // a controller to test, that will use mock of the service: def controller = new UserController(userService) def 'should throw exception for invalid username'() { given: def username = 'Joffrey Baratheon' userService.exists(_ as User) >> false userService.add(_ as User) >> { User user -> throw new IllegalArgumentException(user.name) } when: controller.addUser(username) then: def e = thrown(IllegalArgumentException) e.message == username }
final
로 선언돼 있으면 아무 오류없이 Mock 이 작동하지 않는다.0 * _ // 이 위 이후로는 어떠한 모의객체 호출 행위도 없어야 한다.
Spy()
사용시 스파이 대상 객체에 필드 인젝션이 안된다.@groovy.util.logging.Slf4j
사용시에 Error:Groovyc: The current scope already contains a variable of the name $spock_valueRecorder
오류가 발생하는 경우가 있다. Logger 직접 선언할 것.where
의 변수명에 따라 문제가 발생함. 변수명 수정 필요. groovy 의 문제가 아니라 spock & groovy 2.5 조합일 때 발생하는 버그로 보임.where
의 변수명이 전혀 다른 메소드에서 다른 타입으로 사용되면, 그 다른 타입으로 인식하는 문제. type 이 다르면 변수 이름도 다르게 해야 한다. Parameter type is inferred wrong when local variable with same name is present in unrelated method · Issue #880 · spockframework/spockthen
처럼 각자 assert 를 수행하기 때문에 그럴 필요가 없어짐.// 1.2 방식 1 * mock.foo({ it.size() > 1 && it[0].length == 2 }) // 1.3 - 한줄 한줄의 boolean 반환 결과를 자동 체크함. 1 * mock.foo({ it.size() > 1 it[0].length == 2 })
// Argument capture def extern = null 1 * mock.foo( { extern = it; it.size() > 0 }) // 1.2 방식 1 * mock.foo( { it.size() > 0 }) >> { extern = it[0] } // 1.3 방식