vendredi 27 février 2015

Grails mocking method in service which uses rest plugin

I'm very new to Grails but have been using Ruby on Rails for the past few months, I can't seem to get my head around how to correctly Mock some functionality within a Service I have so I can properly Unit Test it.


I have a RestService which uses a RestBuilder plugin



import javax.persistence.Converter;
import org.codehaus.groovy.grails.web.json.JSONArray
import org.json.JSONObject

import grails.converters.JSON
import grails.plugins.rest.client.RestBuilder
import grails.transaction.Transactional

@Transactional
class RestService {

def retrieveFromRESTClient(url) {
System.properties.putAll( ["http.proxyHost":"proxy.intra.bt.com", "http.proxyPort":"8080", "https.proxyHost":"proxy.intra.bt.com", "https.proxyPort":"8080"] )

def restBuilder = new RestBuilder()
def clientResponse = restBuilder.get(url)

// For development purposes
print "retrieveFromRESTClient: " + clientResponse.json

return clientResponse
}
}


I'm attempting to write a Unit Test for retrieveFromRESTClient() and my thoughts are I should be Mocking the restBuilder.get() plugin call so it doesn't go off and actually do a get request to a URL during the Test. I've attempted a few things already such as extracting the plugin functionality to it's own method:



def retrieveFromRESTClient(url) {
System.properties.putAll( ["http.proxyHost":"proxy.intra.bt.com", "http.proxyPort":"8080", "https.proxyHost":"proxy.intra.bt.com", "https.proxyPort":"8080"] )

def clientResponse = getResponse(url)

// For development purposes
print "retrieveFromRESTClient: " + clientResponse.json

return clientResponse
}

def getResponse(url) {
def restBuilder = new RestBuilder()
def resp = restBuilder.get(url)
resp
}


and in my RestServiceSpec attempting to mock getResponse



import org.springframework.http.ResponseEntity;

import grails.plugins.rest.client.RestBuilder;
import grails.test.mixin.TestFor
import groovy.mock.interceptor.MockFor
import spock.lang.Specification

@TestFor(RestService)
class RestServiceSpec extends Specification {

def cleanup() {
}

void "retrieveFromRESTClient's responses JSON can be accessed"() {
when:
service.metaClass.getResponse { ResponseEntity<String> foo -> return new ResponseEntity(OK) }
def resp = service.retrieveFromRESTClient("http://ift.tt/1MYRQQX")

then:
print resp.dump()
assert resp.json == [:]
}
}


Although this test passes, when I look at resp.dump() in the test-reports I see it's still gone and made a request to 'mocking.so.it.doesnt.matter' and returned that object instead of the mocked ResponseEntity which I assumed it would return.


test-report output:



retrieveFromRESTClient: [:]<grails.plugins.rest.client.RestResponse@433b546f responseEntity=<404 Not Found,<HTML><HEAD>
<TITLE>Network Error</TITLE>
<style>
body { font-family: sans-serif, Arial, Helvetica, Courier; font-size: 13px; background: #eeeeff;color: #000044 }
li, td{font-family: Arial, Helvetica, sans-serif; font-size: 12px}
hr {color: #3333cc; width=600; text-align=center}
{color: #ffff00}
text {color: #226600}
a{color: #116600}
</style>
</HEAD>
<BODY>
<big><strong></strong></big><BR>
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<big>Network Error (dns_unresolved_hostname)</big>
<BR>
<BR>
</TD></TR>
<TR><TD>
RYLCR-BC-20
</TD></TR>
<TR><TD>
Your requested host "mocking.so.it.doesnt.matter" could not be resolved by DNS.
</TD></TR>
<TR><TD>

</TD></TR>
<TR><TD>
<BR>

</TD></TR>
</TABLE>
</blockquote>
</BODY></HTML>
,{Cache-Control=[no-cache], Pragma=[no-cache], Content-Type=[text/html; charset=utf-8], Proxy-Connection=[close], Connection=[close], Content-Length=[784]}> encoding=UTF-8 $json=[:] $xml=null $text=null>


My end goal is to bypass the plugins get call and return a ResponseEntity object. I'm not really sure if I'm using the correct approach for this?


Aucun commentaire:

Enregistrer un commentaire