Grails控制器在集成测试中不返回JSON

时间:2014-11-23 23:32:47

标签: json grails groovy spock

我已经定义了一个控制器:

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客户端他们返回的内容应该采取什么行动)但是我是这个领域的新手而不是了解做错了什么。

0 个答案:

没有答案