You are accessing refId
inappropriately from requestBody
. In your case <person>
is itself represented by requestBody
.
requestBody.refId.text()
will give you 123-abc
.
The controller implementation and the test case should be written this way:
def create() {
if (request.format != "xml") {
render 406 // Only XML expected
return
}
def requestBody = request.XML
def objectType = requestBody.name() as String
//You can see here objectType is person which signifies
//requestBody is represented as the parent tag <person>
log.info "Received ${objectType} - ${requestBody}"
if (!(objectType.toLowerCase() in ['person','personsubtype'])) {
render (status: 400, text: 'Unknown object type received in PUT')
return
}
//Since <person> is represented by requestBody,
//refId can be fetched directly from requestBody
def person = new Person(id: requestBody.refId.text())
person.save()
log.info "Saved ${person}"
render 200
}
Test Class can be optimized and unwanted items can be removed:-
//Test Class can be optimized
import grails.test.mixin.*
import org.junit.*
import com.mycompany.stuff.Person
@TestFor(ServiceController)
//@Mock annotation does the mocking for domain classes
@Mock(Person)
class ServiceControllerTests {
void testCreateWithXML() {
//mockDomain(Person) //Not required, taken care by @Mock
request.method = "PUT"
//No need to initialize controller
//as @TestFor will provide controller.
//def controller = new ServiceController()
controller.request.contentType = 'text/xml'
controller.request.content = '''
<person>
<refId>123-abc</refId>
<otherThing>some stuff</otherThing>
</person>
'''.stripIndent().getBytes() // note we need the bytes (copied from docs)
controller.create()
assert controller.response.contentAsString == 200
assert Person.count() == 1
assertEquals "123-abc", Person.get("123-abc").id
}
}