0

我正在 IBM (此处)上做 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)

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

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)
4

1 回答 1

1

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

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

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

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

于 2013-04-02T14:28:04.113 回答