带有过滤器的 Grails 单元测试没有 return 内容

Grails Unit Test with Filter does not return content

所以我有这个过滤器

package filter.api

import grails.converters.JSON

class ApiFilters {

    def apiService

    def filters = {
        apiSafetyCheck(namespace: "api", controller: "customer|status", action: "*") {
        before = {
            if(!apiService?.checkIncludedApiKey(params)) { //Simply returns true if the apiKey was found in the database!
                def returnMap = [
                    "error": "API key was not found",
                    "statusCode": 401 //Just for testing!
                ]
                if(params.outputFormat && params.outputFormat ?.equals("xml")) {
                    def textToRender = apiService?.createXmlFromMapInstance(returnMap)
                    owner?.render(status: 401, contentType: "text/xml", text: textToRender)
                } else owner?.render(status: 401, contentType: "application/json", text: (returnMap as JSON))
                return false //We don't want the action to be processed!
            }
        }
    }
}

我的单元测试是这样的:

package api

import grails.test.mixin.Mock
import grails.test.mixin.support.GrailsUnitTestMixin
import grails.test.mixin.TestMixin
import grails.test.mixin.TestFor
import groovy.json.JsonSlurper
import groovy.util.XmlSlurper
import java.io.ByteArrayInputStream
import java.io.InputStream
import org.xml.sax.InputSource
import static javax.servlet.http.HttpServletResponse.*
import spock.lang.Specification

@TestMixin([GrailsUnitTestMixin])
@TestFor(BearbeitungController)
@Mock(filter.api.ApiFilters)
class ApiZugriffSpec extends Specification {

    void "Test API wihtout Api Key JSON"() {
        when:
            withFilters(action: "customer") {
                controller.someAction()
            }
        then:
            println "Response from Server " + response.text?.toString()
            println "Test 1 " + response?.getRedirectUrl()
            println "Test 2 " + response?.getRedirectedUrl()
            println "Test 3 " + response?.text
            println "Test 4 " + response.contentType
            def obj = new JsonSlurper().parseText(response.text?.toString())
            println "obj?.statusCode " + obj?.statusCode
            response.contentType == "application/json;charset=UTF-8"
            obj?.statusCode?.toString() == SC_UNAUTHORIZED.toString()
    }

    void "Test API wihtout Api Key XML"() {
        when:
            params.outputFormat = "xml"
            withFilters(action: "customer") {
                controller.someAction()
            }
        then:
            println "Response from Server " + response.text?.toString()
            println "Test 1 " + response?.getRedirectUrl()
            println "Test 2 " + response?.getRedirectedUrl()
            println "Test 3 " + response?.text
            println "Test 4 " + response.contentType
            def xmlSlurperInstance = new XmlSlurper()
            xmlSlurperInstance?.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false)
            xmlSlurperInstance?.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false)
            def inputStream = new ByteArrayInputStream(response.text?.toString()?.getBytes())
            def testXMLArray = xmlSlurperInstance?.parse(new InputSource(inputStream))
            response.contentType == "text/xml"
    }
}

在输出 "Test 3" 上,没有任何内容是可见的,尽管这里应该是我从过滤器呈现的内容...如果我将过滤器编码为重定向到另一个控制器,它也是相同的响应命名空间 "api",它将处理渲染任务。

是否有人已经经历过类似的事情,或者可能知道获得预期结果的解决方法?

我已经自己解决了,我只是从我的过滤器中删除了命名空间,所以过滤器看起来像这样:

package filter.api

import grails.converters.JSON

class ApiFilters {

    def apiService

    def filters = {
        apiSafetyCheck(controller: "customer|status", action: "*") {
        before = {
            if(!apiService?.checkIncludedApiKey(params)) { //Simply returns true if the apiKey was found in the database!
                def returnMap = [
                    "error": "API key was not found",
                    "statusCode": 401 //Just for testing!
                ]
                if(params.outputFormat && params.outputFormat ?.equals("xml")) {
                    def textToRender = apiService?.createXmlFromMapInstance(returnMap)
                    owner?.render(status: 401, contentType: "text/xml", text: textToRender)
                } else owner?.render(status: 401, contentType: "application/json", text: (returnMap as JSON))
                return false //We don't want the action to be processed!
            }
        }
    }
}

就是这样,它对我有用:-)