使用 rest 插件的服务中的 Grails 模拟方法
Grails mocking method in service which uses rest plugin
我是 Grails 的新手,但过去几个月一直在 Rails 上使用 Ruby,我似乎无法理解如何正确模拟其中的某些功能我有一个服务,所以我可以正确地对其进行单元测试。
我有一个 RestService
使用 RestBuilder
插件
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":"some.proxy.host.com", "http.proxyPort":"8080", "https.proxyHost":"some.proxy.host.com", "https.proxyPort":"8080"] )
def restBuilder = new RestBuilder()
def clientResponse = restBuilder.get(url)
// For development purposes
print "retrieveFromRESTClient: " + clientResponse.json
return clientResponse
}
}
我正在尝试为 retrieveFromRESTClient()
编写单元测试,我的想法是我应该模拟 restBuilder.get() 插件调用,这样它就不会关闭并实际执行 get在测试期间请求 URL。我已经尝试了一些事情,例如将插件功能提取到它自己的方法中:
def retrieveFromRESTClient(url) {
System.properties.putAll( ["http.proxyHost":"some.proxy.host.com", "http.proxyPort":"8080", "https.proxyHost":"some.proxy.host.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
}
并且在我的 RestServiceSpec
试图模拟 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://mocking.so.it.doesnt.matter/")
then:
print resp.dump()
assert resp.json == [:]
}
}
虽然这个测试通过了,但当我在测试报告中查看 resp.dump() 时,我发现它仍然消失了,并向 'mocking.so.it.doesnt.matter' 和 return 发出了该对象的请求而不是我认为它会 return.
的模拟 ResponseEntity
测试报告输出:
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>
我的最终目标是绕过插件 get
调用和 return 一个 ResponseEntity
对象。我不确定我是否为此使用了正确的方法?
在你的单元测试中,你模拟了一个期待
的方法
ResponseEntity<String> foo
作为参数。
但是你打电话给:
service.retrieveFromRESTClient("http://mocking.so.it.doesnt.matter/")
参数类型为字符串。所以你的模拟方法没有被调用(方法签名不同)。
将您的模拟方法更改为:
service.metaClass.getResponse { String foo -> return new ResponseEntity(OK) }
它应该可以工作。
我是 Grails 的新手,但过去几个月一直在 Rails 上使用 Ruby,我似乎无法理解如何正确模拟其中的某些功能我有一个服务,所以我可以正确地对其进行单元测试。
我有一个 RestService
使用 RestBuilder
插件
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":"some.proxy.host.com", "http.proxyPort":"8080", "https.proxyHost":"some.proxy.host.com", "https.proxyPort":"8080"] )
def restBuilder = new RestBuilder()
def clientResponse = restBuilder.get(url)
// For development purposes
print "retrieveFromRESTClient: " + clientResponse.json
return clientResponse
}
}
我正在尝试为 retrieveFromRESTClient()
编写单元测试,我的想法是我应该模拟 restBuilder.get() 插件调用,这样它就不会关闭并实际执行 get在测试期间请求 URL。我已经尝试了一些事情,例如将插件功能提取到它自己的方法中:
def retrieveFromRESTClient(url) {
System.properties.putAll( ["http.proxyHost":"some.proxy.host.com", "http.proxyPort":"8080", "https.proxyHost":"some.proxy.host.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
}
并且在我的 RestServiceSpec
试图模拟 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://mocking.so.it.doesnt.matter/")
then:
print resp.dump()
assert resp.json == [:]
}
}
虽然这个测试通过了,但当我在测试报告中查看 resp.dump() 时,我发现它仍然消失了,并向 'mocking.so.it.doesnt.matter' 和 return 发出了该对象的请求而不是我认为它会 return.
的模拟 ResponseEntity测试报告输出:
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>
我的最终目标是绕过插件 get
调用和 return 一个 ResponseEntity
对象。我不确定我是否为此使用了正确的方法?
在你的单元测试中,你模拟了一个期待
的方法ResponseEntity<String> foo
作为参数。
但是你打电话给:
service.retrieveFromRESTClient("http://mocking.so.it.doesnt.matter/")
参数类型为字符串。所以你的模拟方法没有被调用(方法签名不同)。
将您的模拟方法更改为:
service.metaClass.getResponse { String foo -> return new ResponseEntity(OK) }
它应该可以工作。