Java Grails2.2.2 UrlMappings异常测试
是否可以针对这样的url映射实现单元测试Java Grails2.2.2 UrlMappings异常测试,java,unit-testing,grails,Java,Unit Testing,Grails,是否可以针对这样的url映射实现单元测试 "500" (controller: 'error', action: 'handle', exception: MyCustomException) 我试着编写这样的单元测试 @TestFor(UrlMappings) @Mock(ErrorController) class UrlMappingsTest { void test() { assertForwardUrlMapping(500, controller: "e
"500" (controller: 'error', action: 'handle', exception: MyCustomException)
我试着编写这样的单元测试
@TestFor(UrlMappings)
@Mock(ErrorController)
class UrlMappingsTest {
void test() {
assertForwardUrlMapping(500, controller: "error", action: "handle", exception: MyCustomException)
}
}
但是获取了junit.framework.AssertionFailedError:url“500”不匹配任何映射
如果我从UrlMapping.groovy和单元测试中删除exception:MyCustomException,它就会工作。但是我做不到。我知道已经快2年了,但是我昨天也遇到了这个问题,虽然使用了Grails 2.4.4,所以我会在这里发布一个解决方案,以防有人碰到这个问题 如果仅仅编写测试是不够的,那么编写测试所花费的时间比编写实际代码所花费的时间还要多1000%,这就更令人不安了 无论如何,问题是URLMappingSunitestMixin不能处理这种情况 这里报告了一个官方错误: 上个月刚刚推出了一个修复方案 如果您想利用Grails 2.4.4中的修复程序,可以在URLMappingSunitestMixinbugfix中创建一个mixin,然后在UrlMappingsTest中使用它 urlmappingsunitestmixin.groovy UrlMappingsTest.groovy
package com.example.util.test
import grails.util.Holders
import junit.framework.AssertionFailedError
import org.codehaus.groovy.grails.commons.ControllerArtefactHandler
import org.codehaus.groovy.grails.commons.GrailsControllerClass
import org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder
import static junit.framework.Assert.assertEquals
/**
* Methods below are copied from {@link grails.test.mixin.web.UrlMappingsUnitTestMixin}
*
* <p>This method is here because the {@link grails.test.mixin.web.UrlMappingsUnitTestMixin} in Grails 2.4.4 has a bug and this code fixes it.
* <p>Link to the bug: <a href="https://github.com/grails/grails-core/issues/10226">here</a>.
*
* <p>To use this class just write UrlMappingsTest as per Grails guidelines and add a static code block to the Test:
* <p>
* <code>
* static {
* UrlMappingsTest.mixin(UrlMappingsUnitTestMixinBugFix)
* }
* </code>
*/
class UrlMappingsUnitTestMixinBugFix {
void assertForwardUrlMapping(assertions, url) {
assertForwardUrlMapping(assertions, url, null)
}
void assertForwardUrlMapping(assertions, url, paramAssertions) {
def assertionKeys = ["controller", "action", "view"]
final String KEY_EXCEPTION = 'exception'
UrlMappingsHolder mappingsHolder = Holders.applicationContext.getBean("grailsUrlMappingsHolder", UrlMappingsHolder)
if (assertions.action && !assertions.controller) {
throw new AssertionFailedError("Cannot assert action for url mapping without asserting controller")
}
if (assertions.controller) assertController(assertions.controller, url)
if (assertions.action) assertAction(assertions.controller, assertions.action, url)
if (assertions.view) assertView(assertions.controller, assertions.view, url)
def mappingInfos
if (url instanceof Integer) {
mappingInfos = []
// -------- START FIX --------
// -------- OLD CODE (below) --------
// def mapping = mappingsHolder.matchStatusCode(url)
// if (mapping) mappingInfos << mapping
// -------- FIXED CODE (below) --------
def mapping
if (assertions."$KEY_EXCEPTION") {
mapping = mappingsHolder.matchStatusCode(url, assertions."$KEY_EXCEPTION" as Throwable)
} else {
mapping = mappingsHolder.matchStatusCode(url)
}
if (mapping) mappingInfos << mapping
// -------- END FIX --------
} else {
mappingInfos = mappingsHolder.matchAll(url)
}
if (mappingInfos.size() == 0) throw new AssertionFailedError("url '$url' did not match any mappings")
def mappingMatched = mappingInfos.any { mapping ->
mapping.configure(webRequest)
for (key in assertionKeys) {
if (assertions.containsKey(key)) {
def expected = assertions[key]
def actual = mapping."${key}Name"
switch (key) {
case "controller":
if (actual && !getControllerClass(actual)) return false
break
case "view":
if (actual[0] == "/") actual = actual.substring(1)
if (expected[0] == "/") expected = expected.substring(1)
break
case "action":
if (key == "action" && actual == null) {
final controllerClass = getControllerClass(assertions.controller)
actual = controllerClass?.defaultAction
}
break
}
assertEquals("Url mapping $key assertion for '$url' failed", expected, actual)
}
}
if (paramAssertions) {
def params = [:]
paramAssertions.delegate = params
paramAssertions.resolveStrategy = Closure.DELEGATE_ONLY
paramAssertions.call()
params.each { name, value ->
assertEquals("Url mapping '$name' parameter assertion for '$url' failed", value, mapping.params[name])
}
}
return true
}
if (!mappingMatched) throw new IllegalArgumentException("url '$url' did not match any mappings")
}
private GrailsControllerClass getControllerClass(controller) {
return grailsApplication.getArtefactByLogicalPropertyName(ControllerArtefactHandler.TYPE, controller)
}
}
import com.example.controller.ErrorController
import com.example.util.test.UrlMappingsUnitTestMixinBugFix
import grails.test.mixin.Mock
import grails.test.mixin.TestFor
@TestFor(UrlMappings)
@Mock(ErrorController)
class UrlMappingsTest {
static {
UrlMappingsTest.mixin(UrlMappingsUnitTestMixinBugFix)
}
void test() {
assertForwardUrlMapping(500, controller: "error", action: "handle", exception: MyCustomException)
}
}