grails-profiles/rest-api/templates/artifacts/scaffolding/FunctionalSpec.groovy (126 lines of code) (raw):
<%=packageName ? "package ${packageName}" : ''%>
import grails.gorm.transactions.Rollback
import grails.testing.mixin.integration.Integration
import grails.testing.spock.OnceBefore
import io.micronaut.core.type.Argument
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpStatus
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.exceptions.HttpClientResponseException
import spock.lang.AutoCleanup
import spock.lang.Shared
import spock.lang.Specification
@Integration
class ${className}FunctionalSpec extends Specification {
@Shared
@AutoCleanup
HttpClient client
@OnceBefore
void init() {
String baseUrl = "http://localhost:\$serverPort"
this.client = HttpClient.create(new URL(baseUrl))
}
void cleanup() {
assert false, "TODO: Provide a cleanup implementation if using MongoDB"
}
String getResourcePath() {
assert false, "TODO: provide the path to your resource. Example: \"\${baseUrl}/books\""
}
Map getValidJson() {
assert false, "TODO: provide valid JSON"
}
Map getInvalidJson() {
assert false, "TODO: provide invalid JSON"
}
void "Test the index action"() {
when:"The index action is requested"
HttpResponse<List<Map>> response = client.toBlocking().exchange(HttpRequest.GET(resourcePath), Argument.of(List, Map))
then:"The response is correct"
response.status == HttpStatus.OK
response.body() == []
}
@Rollback
void "Test the save action correctly persists an instance"() {
when:"The save action is executed with no content"
client.toBlocking().exchange(HttpRequest.POST(resourcePath, ""))
then:"The response is correct"
def e = thrown(HttpClientResponseException)
e.response.status == HttpStatus.UNPROCESSABLE_ENTITY
when:"The save action is executed with invalid data"
client.toBlocking().exchange(HttpRequest.POST(resourcePath, invalidJson))
then:"The response is correct"
e = thrown(HttpClientResponseException)
e.response.status == HttpStatus.UNPROCESSABLE_ENTITY
when:"The save action is executed with valid data"
HttpResponse<Map> response = client.toBlocking().exchange(HttpRequest.POST(resourcePath, validJson), Map)
then:"The response is correct"
response.status == HttpStatus.CREATED
response.body().id
${className}.count() == 1
cleanup:
def id = response.body().id
def path = "\${resourcePath}/\${id}"
response = client.toBlocking().exchange(HttpRequest.DELETE(path))
assert response.status() == HttpStatus.NO_CONTENT
}
void "Test the update action correctly updates an instance"() {
when:"The save action is executed with valid data"
HttpResponse<Map> response = client.toBlocking().exchange(HttpRequest.POST(resourcePath, validJson), Map)
then:"The response is correct"
response.status == HttpStatus.CREATED
response.body().id
when:"The update action is called with invalid data"
String path = "\${resourcePath}/\${response.body().id}"
client.toBlocking().exchange(HttpRequest.PUT(path, invalidJson), Map)
then: "The response is unprocessable entity"
path
def e = thrown(HttpClientResponseException)
e.response.status == HttpStatus.UNPROCESSABLE_ENTITY
when: "The update action is called with valid data"
response = client.toBlocking().exchange(HttpRequest.PUT(path, validJson), Map)
then:"The response is correct"
response.status == HttpStatus.OK
response.body()
cleanup:
response = client.toBlocking().exchange(HttpRequest.DELETE(path))
assert response.status() == HttpStatus.NO_CONTENT
}
void "Test the show action correctly renders an instance"() {
when:"The save action is executed with valid data"
HttpResponse<Map> response = client.toBlocking().exchange(HttpRequest.POST(resourcePath, validJson), Map)
then:"The response is correct"
response.status == HttpStatus.CREATED
response.body().id
when:"When the show action is called to retrieve a resource"
def id = response.body().id
String path = "\${resourcePath}/\${id}"
response = client.toBlocking().exchange(HttpRequest.GET(path), Map)
then:"The response is correct"
response.status == HttpStatus.OK
response.body().id == id
cleanup:
client.toBlocking().exchange(HttpRequest.DELETE(path))
}
@Rollback
void "Test the delete action correctly deletes an instance"() {
when:"The save action is executed with valid data"
HttpResponse<Map> response = client.toBlocking().exchange(HttpRequest.POST(resourcePath, validJson), Map)
then:"The response is correct"
response.status == HttpStatus.CREATED
response.body().id
when:"When the delete action is executed on an unknown instance"
def id = response.body().id
def path = "\${resourcePath}/99999"
client.toBlocking().exchange(HttpRequest.DELETE(path))
then:"The response is correct"
def e = thrown(HttpClientResponseException)
e.response.status == HttpStatus.NOT_FOUND
when:"When the delete action is executed on an existing instance"
path = "\${resourcePath}/\${id}"
response = client.toBlocking().exchange(HttpRequest.DELETE(path))
then:"The response is correct"
response.status == HttpStatus.NO_CONTENT
!${className}.get(id)
}
}