简体   繁体   中英

Unable to call a groovy closure

I am using ws-lite to automate web service testing, and I want to have more flexible control over the xm l request generated.

Basically the request body is a groovy closure that will be passed to MarkupBuilder in order to create the SOAP message.

Here is an example of what I am trying to achieve (example taken from https://github.com/jwagenleitner/groovy-wslite ):

@Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.0')
import wslite.soap.*

def client = new SOAPClient('http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx')
def month = ["Feb"]

def response = client.send(SOAPAction:'http://www.27seconds.com/Holidays/US/Dates/GetMothersDay') {
    body {
        GetMothersDay('xmlns':'http://www.27seconds.com/Holidays/US/Dates/') {
            year(2011)
            month.each{ a = null ->
                                        if (a != null){
                                            "month"(a)
                                        }
                                    }
        }
    }
}

assert "2011-05-08T00:00:00" == response.GetMothersDayResponse.GetMothersDayResult.text()
assert 200 == response.httpResponse.statusCode
assert "ASP.NET" == response.httpResponse.headers['X-Powered-By']

The above example, I can create month tag fine with value/values specified.

But if I change it to be:

@Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.0')
import wslite.soap.*

def client = new SOAPClient('http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx')
def month_cl = { a -> "month"(a) }

def response = client.send(SOAPAction:'http://www.27seconds.com/Holidays/US/Dates/GetMothersDay') {
    body {
        GetMothersDay('xmlns':'http://www.27seconds.com/Holidays/US/Dates/') {
            year(2011)
            month_cl("Feb")
        }
    }
}

assert "2011-05-08T00:00:00" == response.GetMothersDayResponse.GetMothersDayResult.text()
assert 200 == response.httpResponse.statusCode
assert "ASP.NET" == response.httpResponse.headers['X-Powered-By']

I will have a missing method exception.

I don't quite understand why I can't just invoke a groovy closure like that?

Delegate of month_cl closure has to be set to the current/parent delegate (in this case it is closure passed as param to GetMothersDay ). Try with:

body {
    GetMothersDay('xmlns':'http://www.27seconds.com/Holidays/US/Dates/') {
        year(2011)
        month_cl.delegate = delegate
        month_cl("Feb")
    }
}

It's quite normal to get MissingMethodException , because the closure month_cl is calling month method which does not exist. To do this (in your way), you should pass a Closure c to month_cl and call it on the argument a , like this:

def month_cl = { a, Closure c -> c(a) }

and using the new implementation, month_cl("Feb") becomes month_cl("Feb") { "month" } which results to "month"("Feb") .

Here is a working example:

@Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.0')
import wslite.soap.*

def client = new SOAPClient('http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx')
def months = ["Feb"]
def month_cl = { m, Closure c -> return c(m) }

def response = client.send(SOAPAction:'http://www.27seconds.com/Holidays/US/Dates/GetMothersDay') {
    body {
        GetMothersDay('xmlns':'http://www.27seconds.com/Holidays/US/Dates/') {
            year(2011)
            month_cl("Feb") { "month" }  // -> month("Feb")
        }
    }
}

assert "2011-05-08T00:00:00" != response.GetMothersDayResponse.GetMothersDayResult.text()
assert 200 == response.httpResponse.statusCode
assert "ASP.NET" == response.httpResponse.headers['X-Powered-By']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM