IBM (here)에서 Grails 튜토리얼을 작성하고 있지만 통합 테스트에 실망합니다. 요약 : ID (iata)에 따라 JSON 객체를 렌더링하는 메소드를 호출합니다.Grails의 통합 테스트에서의 이상한 동작
내 도메인이다 :
class Airport {
String name
String iata
}
내 제어기는 :
class AirportController {
// In order to enable scaffolding
def scaffold = Airport
def iata = {
def iata = params.id?.toUpperCase() ?: "NO IATA"
def airport = Airport.findByIata(iata)
if (!airport) {
airport = new Airport(iata: iata, name: "Not found")
}
render airport as JSON
}
}
I가 수행 할 때 http://localhost:8080/trip-planner/airport/iata/foo
(덴버) http://localhost:8080/trip-planner/airport/iata/DEN
또는 (널값 retreive하기 위해), 본 방법을 잘 작동합니다!
class AirportControllerTests extends GroovyTestCase {
void testWithGoodIata(){
def controller = new AirportController()
controller.metaClass.getParams = { ->
return ["id":"den"]
}
controller.iata()
def response = controller.response.contentAsString
assertTrue response.contains("Denver")
}
void testWithWrongIata() {
def controller = new AirportController()
controller.metaClass.getParams = { ->
return ["id":"foo"]
}
controller.iata()
def response = controller.response.contentAsString
assertTrue response.contains("\"name\":\"Not found\"")
}
}
문제는 다음과 같습니다 : 나는 (실행하여 : grails test-app -integration trip.planner.AirportControllerTests
를) 테스트를 실행 할 때마다
, 난 항상 첫 번째 테스트에서 좋은 행동을 얻을 것이다
문제는 내 통합 테스트입니다 a groovy.lang.MissingMethodException
초 시험. (두 개를 전환하더라도 두 번째 테스트는 항상 실패 함)
별도로 실행하면 작동합니다. (컨트롤러에서)이 줄에서 예외가 발생했습니다 : def airport = Airport.findByIata(iata)
"트랜잭션"과 관련이 있습니까? 어떤 도움도 큰 :)
PS 될 것이다 : 나는 Grails의
2.2.1를 사용하고 예외 스택 트레이스 :
groovy.lang.MissingMethodException: No signature of method: trip.planner.Airport.methodMissing() is applicable for argument types:() values: []
at trip.planner.AirportController$_closure4.doCall(AirportController.groovy:39)
at trip.planner.AirportControllerTests.testWithWrongIata(AirportControllerTests.groovy:25)
코드를 향상시킬 수있는 몇 가지 질문 (문제 해결에 도움이 될 수 있음) : 데이터베이스를 쿼리하는 논리가 컨트롤러 내부에있는 이유는 무엇입니까? 비즈니스 로직이 없으면 요청 및 응답을 처리 할 책임 만있는 단위 테스트에서 컨트롤러 동작을 테스트 할 수 있어야합니다. 둘째, 공항을 찾기 위해 가짜 ID를 사용하지 말고 'NO IATA'대신 단순히 null을 사용하십시오. – lucke84
로직이 컨트롤러 내부에있는 이유는 무엇입니까? 컨트롤러가 로직을 수행해야하기 때문에 여기에 있습니다 (IBM에서 자습서를 진행하고 있습니다). 나는 "NO IATA"를 null로 대체하지만 문제를 해결하지 못합니다. –
죄송합니다. 자신을 잘 설명하지 않았습니다. 논리는 물론 필요하지만 컨트롤러가 아닌 서비스 내부에 있어야합니다. – lucke84