2013-04-02 3 views
0

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) 
+0

코드를 향상시킬 수있는 몇 가지 질문 (문제 해결에 도움이 될 수 있음) : 데이터베이스를 쿼리하는 논리가 컨트롤러 내부에있는 이유는 무엇입니까? 비즈니스 로직이 없으면 요청 및 응답을 처리 할 책임 만있는 단위 테스트에서 컨트롤러 동작을 테스트 할 수 있어야합니다. 둘째, 공항을 찾기 위해 가짜 ID를 사용하지 말고 'NO IATA'대신 단순히 null을 사용하십시오. – lucke84

+0

로직이 컨트롤러 내부에있는 이유는 무엇입니까? 컨트롤러가 로직을 수행해야하기 때문에 여기에 있습니다 (IBM에서 자습서를 진행하고 있습니다). 나는 "NO IATA"를 null로 대체하지만 문제를 해결하지 못합니다. –

+0

죄송합니다. 자신을 잘 설명하지 않았습니다. 논리는 물론 필요하지만 컨트롤러가 아닌 서비스 내부에 있어야합니다. – lucke84

답변

1

나는 메타 클래스는 어떻게 든 누출되는 하나 개의 테스트에서 만들고있어 변경 의심 통해 다른쪽으로. 그러나 당신은 당신 만 단위 테스트를 위해 조롱 할 필요가

def controller = new AirportController() 
controller.params.id = "den" 

말을 할 필요가 없습니다 (그리고 안)을 통합 시험의 메타 클래스를 조작 할 수 있습니다.

당신이보고있는 튜토리얼은 2008 년 (Grails 1.0.x)에 작성되었으며, Grails는 그 이후로 매우 오랜 시간 동안 테스트를 포함한 일부 구성 요소로 옮겨왔다. 하나 이상의 완전한 재 작성을 거쳤습니다.

+0

감사합니다. 다른 튜토리얼을 찾아야 할 수도 있습니다 ... MetaClass를 조작하지 않기 위해 말한 내용을 변경했지만 불행하게도 아무 것도 변경하지 않습니다. –

+0

@GuillaumeM 질문을 편집하여 'MissingMethodException'의 전체 세부 정보 (및 스택 추적)를 포함 할 수 있습니까? 분명히 누락 된 방법과 누가 그것을 호출하려고합니까? –

+0

완료. 그것은 매우 이상합니다. 두 테스트에서 정확히 같은 메소드를 호출하기 때문입니다. –