我已经定义了一个控制器:
class FamilyController extends RestfulController {
def springSecurityService
def familyService
static responseFormats = ['json']
FamilyController() {
super(Family)
}
@Override
protected List<Family> listAllResources(Map params) {
def user = springSecurityService.loadCurrentUser()
return Family.findAllByUser(user)
}
@Override
protected Family createResource() {
//def instance = super.createResource()
//TODO: Should be able to run the above line but there is an issue GRAILS-10411 that prevents it.
// Code from parent is below, as soon as the jira is fixed, remove the following lines:
def p1 = params
def p2 = getObjectToBind()
Family instance = resource.newInstance()
bindData instance, getObjectToBind()
/*
* In unit testing, the bindData operation correctly binds the params
* data to instance properties. When running with integration tests,
* this doesn't happen and I have to do the property assignment myself.
* Not sure if this breaks anything elsewhere.
*/
instance.properties = p1
//Code from super ends here
familyService.addFamilyToUser(instance)
return instance
}
@Override
protected Family queryForResource(Serializable id) {
def inst = familyService.safeGetFamily(Long.parseLong(id))
return inst
}
public create()
{
Family r = this.createResource()
render r as JSON
}
public index()
{
render this.listAllResources(params) as JSON
}
}
出于迂腐的目的(我是grails / groovy的新手,我想观察控制器的工作),我想看看控制器中各种动作的实际结果。所以我构建了一个集成测试:
@Mock([AdultPlanning, Primary, Secondary, Child, Family, Tenant, User])
class FamilyControllerIntegrationSpec extends IntegrationSpec {
Tenant tenant
User user
FamilyController controller = new FamilyController()
FamilyService familyService = new FamilyService()
def setupSpec() {
tenant = new Tenant(name: 'MMSS')
user = new User(subject: "What is a subject?", identityProvider: "http://google.com/")
tenant.addToUsers(user)
tenant.save()
user.save() // The tenant save should propagate to the user, this is to make sure.
/*
* Set up the custom marshalling code for family objects.
*/
new AdultPlanningMarshaller()
new ChildMarshaller()
new FamilyMarshaller()
new FamilyTypeEnumMarshaller()
return
}
def cleanup() {
}
void "Create a Family"() {
when:
def mSpringSecurityService = mockFor(SpringSecurityService)
/*
* I expect to make n calls (1..3) on loadCurrentUser in this test.
*/
mSpringSecurityService.demand.loadCurrentUser(1..3) { -> return user }
controller.springSecurityService = mSpringSecurityService.createMock()
controller.request.contentType = 'text/json'
controller.index()
def json
try {
json = controller.response.json
}
catch (e)
{
json = null // action didn't emit any json
}
def text = controller.response.text
then:
!json
text == "[]"
when:
controller.params.name = "Test"
controller.params.typeOfFamily = FamilyTypeEnum.SINGLE
controller.familyService.springSecurityService = controller.springSecurityService //mSpringSecurityService.createMock()
/*
* I've tried both GET (default) and POST to get bindData to pick up parameters properly,
* with no joy.
*/
// controller.request.method = "POST"
controller.request.contentType = 'text/json'
controller.create()
try {
json = controller.response.json
}
catch (e)
{
json = null // action didn't emit any json
}
text = controller.response.text
then:
1 == 1
when:
controller.index()
json = controller.response.json
then:
json.name == "Test"
}
}
所以在第一个块时,我没有列出任何系列(并在响应中清空json对象和一个[]字符串),这是我所期望的,但直到我实际在代码中实现了索引操作,我才得到json从我没想到的行动中回来。
到第二天的时候。我创建了一个系列(使用dataBinding存在问题,但我先解决了一个变通方法,首先是第一件事)并且创建并保存了系列,但响应中没有任何内容。我已经使用了调试器,我看到JSON编组器触发了新创建的系列,因此SOMETHING正在渲染JSON但是它在哪里?。
所以我显然做错了什么(或者我不明白为了传递给Web客户端他们返回的内容应该采取什么行动)但是我是这个领域的新手而不是了解做错了什么。