Grails 2.4.4。 我们有很多JSON / REST API端点,如下所示,但代码更多(注意:我们不能使用RestfulController,因为我们有SpringSecurity而且它们不兼容)
e.g。
class SessionController
def sessionService
static namespace = 'v1'
static allowedMethods = [loginPlayer: "POST"]
def loginPlayer() {
def payload = request.JSON
try {
// Check params are there.
if (payload.user == null) {
render(status: 422, contentType: 'application/json') {
[
'result' : -1
'description': "missing params"
]
return
}
def result = sessionService.loginPlayer(
payload.user,
payload.password
)
if (result.returnCode == 0) {
render(status: 200, contentType: 'application/json') {
[
'result' : 0
'authToken' : result.authToken
etc.
我们目前正在使用SOAPUI手动测试它们。我们迫切希望自动化集成测试能够针对数据库测试整个API的端到端。
我们尝试了这个:
class SessionControllerIntegrationSpec extends IntegrationSpec {
SessionController controller
def setup() {
}
def cleanup() {
}
void "test login"() {
controller = new SessionController()
controller.request.contentType = 'application/json'
controller.request.format = 'json'
controller.response.format = 'json'
when:
controller.request.content =
'{"user":"someuser","password":"somepass"}'.getBytes()
def model = controller.loginPlayer()
then:
model != null
}
}
但它总是返回null作为模型。
也尝试过:
class SessionControllerIntegrationSpec extends GroovyTestCase {
:
def sessionService
:
controller.sessionService = sessionService
根据传递“testing controllers with services”
的说明但这没有帮助 - 结果仍然无效。同时扩展GroovyTestCase意味着回到断言。
我们正在尝试做甚么可能吗?
我们看到有些人通过点击localhost的外部URL进行集成测试,例如:
class ExampleWebAppSpecification extends Specification {
def "Should return 200 & a message with the input appended"() {
setup:
def primerEndpoint = new RESTClient( 'http://localhost:8080/' )
when:
def resp = primerEndpoint.get([ path: 'exampleendpoint', query : [ input : 'Get a hair cut' ]])
then:
with(resp) {
status == 200
contentType == "application/json"
}
with(resp.data) {
payload == "Something really important: Get a hair cut"
}
} }
这与使用jmeter或其他工具测试正在运行的服务器并没有太大区别,并且具有很多依赖性。
任何提示或建议?
更新1:
找到了一个这样做的例子
assert controller.response.getStatus() == 200
在调试器中,controller.response.getStatus()返回405(我们的控制器永远不会返回的状态),controller.response.contentAsString返回“”。
当我们在调试器中运行测试时,永远不会调用Controllers代码。所以问题可能是grails根本没有注入SessionController。
更新2
猜测问题出在请求方法上,尝试添加:
controller.request.requestMethod = HttpMethod.POST
然而,这仍然会产生405。
在REST控制器中,我们有:
static allowedMethods = [loginPlayer: "POST"]
如果我发表评论,我会收到预期的回复!
现在的问题是如何让测试使用POST(设置requestMethod似乎没有这样做),或者如果控制器处于测试模式下如何更改控制器以接受GET?
更新3 - 解决了!下面的工作代码:
类SessionControllerIntegrationSpec扩展了IntegrationSpec def sessionService
class SessionControllerIntegrationSpec extends IntegrationSpec {
SessionController controller
void "test login"() {
controller = new SessionController() // must manually create
controller.sessionService = sessionService // must manually inject
controller.request.contentType = 'application/json'
controller.request.format = 'json'
controller.response.format = 'json'
controller.request.requestMethod = HttpMethod.POST
controller.request.method = 'POST'
when:
controller.request.content =
'{"user":"someuser","password":"somepass"}'.getBytes()
then:
assert controller.response.getStatus() == 200
print "CONTENT: " + controller.response.contentAsString
// now can use string search functions to check the JSON data returned.