테스트 자동화에 사용할 자바 애플리케이션을위한 그루비 휴식 클라이언트를 만들고 있습니다. 나는 원래 httpBuilder에서 서비스를 작성했지만 응답을 구문 분석하는 방법을 알 수 없었다. 200이 아닌 응답에서 나는 메시지에 붙잡을 수있는 예외를 얻었다. 찾을 수 없습니다, 나쁜 요청 등. 업데이트 후, 나는 응답을 구문 분석 할 수 있지만 언제든지 내가 아닌 200 응답을 얻을, 내 개체로 다음 쓸모없는 'missingProperty'예외를 throw합니다 구문 분석을 시도합니다. 이 문서는 response.parser <CONTENT_TYPE>, { config, fs ->...}
을 사용하여 응답을 구문 분석하는 방법과 response.success{fs -> ...}
또는 response.when(<CODE>){fs -> ...}
을 사용하여 상태 코드를 분기하는 방법을 보여 주지만 성공에 대해서만 구문 분석하고 실패에 대해서는 다른 논리를 사용하는 방법을 설명하지 않습니다.HttpBuilder-ng를 사용하여 성공을 파싱하거나 오류를 던질 수있는 방법
import groovyx.net.http.ChainedHttpConfig
import groovyx.net.http.FromServer
import groovyx.net.http.HttpBuilder
import groovyx.net.http.NativeHandlers
import static groovyx.net.http.ContentTypes.JSON
import static groovyx.net.http.NativeHandlers.Parsers.json
class CarClient {
private final HttpBuilder http
CarClient() {
http = HttpBuilder.configure {
request.uri = "localhost:8080"
request.encoder JSON, NativeHandlers.Encoders.&json
}
}
List<Car> getCars(make) {
http.get(List) {
request.uri.path = "/cars/make/${make}"
response.failure { fs ->
println("request failed: ${fs}")
}
response.parser JSON, { ChainedHttpConfig config, FromServer fs ->
json(config, fs).collect { x -> new Car(make: x."make", model: x."model") }
}
}
}
}
class Car {
def make
def model
}
내 스팍 테스트 : : 첫 번째 테스트가 실패 이전 버전에서
def "200 response should return list of cars"() {
when:
def result = client.getCars("honda")
then:
result.size == 3
result[0].make == "honda"
result[0].model == "accord"
}
def "404 responses should throw exception with 'not found'"() {
when:
client.getCars("ford")
then:
final Exception ex = thrown()
ex.message == "Not Found"
}
하고, 전달 된 두 번째 테스트를 다음과 같이 내 현재 코드입니다. 새 버전에서는 첫 번째 테스트가 통과되고 두 번째 테스트가 실패합니다. 실제로는 request failed:...
메시지도 볼 수 없습니다. 방금 groovy.lang.MissingPropertyException
이 표시됩니다. 단계를 밟을 때 not found
응답을 Car 객체로로드하려고 시도하는 것을 볼 수 있습니다.
보너스 : 문서에서와 같이 그루비 캐스팅 대신 명시적인 속성 매핑을 사용해야하는 이유는 무엇입니까?
json(config, fs).collect { x -> x as Car }
업데이트 - 설명을 위해 이것은 실제 소스가 아닙니다. WAS에서 실행되는 독점적 인 내부 API를 사용하고 있는데, 완전히 제어하지는 않습니다. API의 비즈니스 로직을 작성 중이지만 액세스 권한이없는 WAS 및 독점 라이브러리를 사용하여 응답을 마샬링/언 마샬링하고 있습니다. 무고한/내 일을 보호하기 위해 이름이 변경되었습니다. 다음은 초기 게시 이후 시도한 해결 방법입니다. 이렇게하면 200이 아닌 응답에서 오류 블록이 올바르게 트리거되지만 구문 분석은 IO - stream closed
오류로 실패합니다. 또한, 내가 실패 블록에 던져 모든 예외 정보에 액세스하지 못하도록 RuntimeException 래핑 얻을. 나는 문서에서 제안 된 전송 예외에 래핑 시도했다,하지만 여전히 그것을 얻을 때까지 RuntimeException 있어요.
List<Car> getCars(make) {
http.get(List) {
request.uri.path = "/cars/make/${make}"
response.failure { fs ->
println("request failed: ${fs}")
throw new AutomationException("$fs.statusCode : $fs.message")
}
response.success { FromServer fs ->
new JsonSlurper().parse(new InputStreamReader(fs.getInputStream, fs.getCharset())).collect { x -> new Car(make: x."make", model: x."model") }
}
}
}
}
이 항목은 항목이있는 200 개의 응답에서 올바르게 구문 분석되지만 항목이없는 200은 여전히 속성 예외가 누락되었습니다. 이전 impl과 마찬가지로 AutomationException은 래핑되어 유용하지 않습니다. 보너스에 대해서는
는List<Car> getCars(make) {
http.get(List) {
request.uri.path = "/cars/make/${make}"
response.parser JSON, { ChainedHttpConfig config, FromServer fs ->
if (fs.statusCode == 200) {
json(config, fs).collect { x -> new Car(make: x."make", model: x."model") }
} else {
throw new AutomationException("$fs.statusCode : $fs.message")
}
}
}
}
, 가이드 나는 자동차 개체에 json(config, fs)
출력의 암시 적 캐스팅을 보여 다음되었다. 명시 적으로 새 객체의 소품을 설정해야합니다. 큰 문제는 아니지만 내가 다른 것을 잘못 구성했는지 궁금합니다.
@ thejames42이 문제가 해결 되었습니까? – cjstehno
불행히도 아닙니다. 문제는 응답이 항상 콘텐츠 유형'application/json'으로 돌아오고 있기 때문에 파서가 항상 시작된다는 것입니다. 나는 파서를 제거하고 성공 클로저에서 '새로운 JSONSlurper (... fs.getIntputStream)를 호출하려고 시도했지만'스트림 닫힘 '오류가 발생합니다. 지금까지 네이티브 처리기를 호출하기 전에 파서 클로저에 try catch를 추가하는 것이 가장 좋았지 만 예외 처리는 혼란스럽고 여전히 빈 목록을 반환하는 200에서 질식합니다. 테스트를 만들려고했는데, 그것은 부작용 이었으므로 작업 할 시간이별로 들지 않았습니다. – thejames42