Grails集成测试中的奇怪行为

时间:2013-04-02 13:14:08

标签: grails integration-testing missingmethodexception

我在IBM (here)上做Grails教程,但我对集成测试非常失望。 总结一下:我调用一个根据ID(iata)呈现JSON对象的方法。

我的域名是:

 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
    }    
}

当我这样做时: http://localhost:8080/trip-planner/airport/iata/foo(为了检索空值)或 http://localhost:8080/trip-planner/airport/iata/DEN(对于DENVER),该方法运行正常!

问题是我的集成测试:

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),我将始终在第一次测试中获得良好的行为,并在第二次测试中获得groovy.lang.MissingMethodException。 (即使我切换了两个:第二个测试总是失败)

如果我单独运行它,它可以工作。 此行发生异常(在控制器中):def airport = Airport.findByIata(iata)

这与“交易”有关吗?任何帮助都会很棒:)

P.S:我正在使用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)

1 个答案:

答案 0 :(得分:1)

我怀疑你在一次测试中所做的元类改变是以某种方式泄漏到另一个。但是你不需要(也不应该)在集成测试中操作元类,只需说

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

您只需要对单元测试进行模拟。

请记住,您正在查看的教程是在2008年(Grails 1.0.x天)中编写的,Grails从那时起已经走了很长一段路,其中包含一些组件(包括测试)通过一次或多次完整的重写。