- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新 3 - 通过和失败的示例
由于这篇文章的长度,所以不允许我粘贴它们,因此可以在这里找到示例:http://pastebin.com/gMVa4Gd1
更新#2。根据有关更新脚手架插件版本的建议答案,我重新运行了generate-all '*'命令和测试。这是更新后的输出,下面是生成的代码:
| Error Forked Grails VM exited with error
| Environment set to development.....
| Running without daemon...
| Running 2 unit tests...
| Running 2 unit tests... 1 of 2
| Running 2 unit tests... 2 of 2
| Running 2 unit tests... 3 of 3
| Failure: Test the save action correctly persists an instance(AddressControllerSpec)
| org.codehaus.groovy.grails.web.servlet.mvc.exceptions.CannotRedirectException: Cannot redirect for object [Address : (unsaved)] it is not a domain or has no identifier. Use an explicit redirect instead
at AddressController.tt__save_closure9_closure14(AddressController.groovy:43)
at AddressController.$tt__save(AddressController.groovy:40)
at AddressControllerSpec.Test the save action correctly persists an instance(AddressControllerSpec.groovy:54)
| Running 2 unit tests... 4 of 4
| Running 2 unit tests... 5 of 5
| Running 2 unit tests... 6 of 6
| Error 2014-06-06 09:39:45,246 [main] ERROR mvc.GrailsParameterMap - Error processing form encoded PUT request
Message: null
Line | Method
->> 98 | doCall in AddressController$_notFound_closure8_closure12
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 96 | notFound in AddressController
| 56 | $tt__update . . . . . . . in ''
| 98 | $spock_feature_0_5 in AddressControllerSpec
| 138 | invokeMethod . . . . . . in org.spockframework.util.ReflectionUtil
| 330 | invokeRaw in org.spockframework.runtime.BaseSpecRunner
| 311 | invoke . . . . . . . . . in ''
| 285 | invokeFeatureMethod in ''
| 256 | doRunIteration . . . . . in ''
| 138 | invokeMethod in org.spockframework.util.ReflectionUtil
| 91 | invokeTargetMethod . . . in org.spockframework.runtime.extension.MethodInvocation
| 85 | proceed in ''
| 37 | evaluate . . . . . . . . in org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1
| 48 | evaluate in grails.test.runtime.TestRuntimeJunitAdapter$1$2
| 38 | intercept . . . . . . . . in org.spockframework.runtime.extension.builtin.TestRuleInterceptor
| 84 | proceed in org.spockframework.runtime.extension.MethodInvocation
| 319 | invoke . . . . . . . . . in org.spockframework.runtime.BaseSpecRunner
| 223 | runIteration in ''
| 214 | initializeAndRunIteration in ''
| 205 | runSimpleFeature in ''
| 199 | doRunFeature . . . . . . in ''
| 138 | invokeMethod in org.spockframework.util.ReflectionUtil
| 330 | invokeRaw . . . . . . . . in org.spockframework.runtime.BaseSpecRunner
| 311 | invoke in ''
| 175 | runFeature . . . . . . . in ''
| 152 | runFeatures in ''
| 112 | doRunSpec . . . . . . . . in ''
| 138 | invokeMethod in org.spockframework.util.ReflectionUtil
| 91 | invokeTargetMethod . . . in org.spockframework.runtime.extension.MethodInvocation
| 85 | proceed in ''
| 37 | evaluate . . . . . . . . in org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1
| 74 | evaluate in grails.test.runtime.TestRuntimeJunitAdapter$3$4
| 38 | intercept . . . . . . . . in org.spockframework.runtime.extension.builtin.ClassRuleInterceptor
| 84 | proceed in org.spockframework.runtime.extension.MethodInvocation
| 319 | invoke . . . . . . . . . in org.spockframework.runtime.BaseSpecRunner
| 91 | runSpec in ''
| 82 | run . . . . . . . . . . . in ''
| 63 | run in org.spockframework.runtime.Sputnik
| 127 | runChild . . . . . . . . in org.junit.runners.Suite
| 26 | runChild in ''
| 238 | run . . . . . . . . . . . in org.junit.runners.ParentRunner$3
| 63 | schedule in org.junit.runners.ParentRunner$1
| 236 | runChildren . . . . . . . in org.junit.runners.ParentRunner
| 53 | access$000 in ''
| 229 | evaluate . . . . . . . . in org.junit.runners.ParentRunner$2
| 309 | run in org.junit.runners.ParentRunner
| 160 | run . . . . . . . . . . . in org.junit.runner.JUnitCore
^ 138 | run in ''
| Failure: Test the update action performs an update on a valid domain instance(AddressControllerSpec)
| java.lang.NullPointerException: Cannot get property 'id' on null object
at AddressControllerSpec.Test the update action performs an update on a valid domain instance(AddressControllerSpec.groovy:122)
| Running 2 unit tests... 7 of 7
| Failure: Test that the delete action deletes an instance if it exists(AddressControllerSpec)
| Condition not satisfied:
Address.count() == 1
| |
0 false
at AddressControllerSpec.Test that the delete action deletes an instance if it exists(AddressControllerSpec.groovy:142)
| Completed 7 unit tests, 3 failed in 0m 10s
Configuring Spring Security Core ...
... finished configuring Spring Security Core
| Tests FAILED
| Error Forked Grails VM exited with error
/************************************* AddressControllerSpec ********************************************/
import grails.test.mixin.*
import spock.lang.*
@TestFor(AddressController)
@Mock(Address)
class AddressControllerSpec extends Specification {
def populateValidParams(params) {
assert params != null
// TODO: Populate valid properties like...
//params["name"] = 'someValidName'
}
void "Test the index action returns the correct model"() {
when:"The index action is executed"
controller.index()
then:"The model is correct"
!model.addressInstanceList
model.addressInstanceCount == 0
}
void "Test the create action returns the correct model"() {
when:"The create action is executed"
controller.create()
then:"The model is correctly created"
model.addressInstance!= null
}
void "Test the save action correctly persists an instance"() {
when:"The save action is executed with an invalid instance"
request.contentType = FORM_CONTENT_TYPE
request.method = 'POST'
def address = new Address()
address.validate()
controller.save(address)
then:"The create view is rendered again with the correct model"
model.addressInstance!= null
view == 'create'
when:"The save action is executed with a valid instance"
response.reset()
populateValidParams(params)
address = new Address(params)
controller.save(address)
then:"A redirect is issued to the show action"
response.redirectedUrl == '/address/show/1'
controller.flash.message != null
Address.count() == 1
}
void "Test that the show action returns the correct model"() {
when:"The show action is executed with a null domain"
controller.show(null)
then:"A 404 error is returned"
response.status == 404
when:"A domain instance is passed to the show action"
populateValidParams(params)
def address = new Address(params)
controller.show(address)
then:"A model is populated containing the domain instance"
model.addressInstance == address
}
void "Test that the edit action returns the correct model"() {
when:"The edit action is executed with a null domain"
controller.edit(null)
then:"A 404 error is returned"
response.status == 404
when:"A domain instance is passed to the edit action"
populateValidParams(params)
def address = new Address(params)
controller.edit(address)
then:"A model is populated containing the domain instance"
model.addressInstance == address
}
void "Test the update action performs an update on a valid domain instance"() {
when:"Update is called for a domain instance that doesn't exist"
request.contentType = FORM_CONTENT_TYPE
request.method = 'PUT'
controller.update(null)
then:"A 404 error is returned"
response.redirectedUrl == '/address/index'
flash.message != null
when:"An invalid domain instance is passed to the update action"
response.reset()
def address = new Address()
address.validate()
controller.update(address)
then:"The edit view is rendered again with the invalid instance"
view == 'edit'
model.addressInstance == address
when:"A valid domain instance is passed to the update action"
response.reset()
populateValidParams(params)
address = new Address(params).save(flush: true)
controller.update(address)
then:"A redirect is issues to the show action"
response.redirectedUrl == "/address/show/$address.id"
flash.message != null
}
void "Test that the delete action deletes an instance if it exists"() {
when:"The delete action is called for a null instance"
request.contentType = FORM_CONTENT_TYPE
request.method = 'DELETE'
controller.delete(null)
then:"A 404 is returned"
response.redirectedUrl == '/address/index'
flash.message != null
when:"A domain instance is created"
response.reset()
populateValidParams(params)
def address = new Address(params).save(flush: true)
then:"It exists"
Address.count() == 1
when:"The domain instance is passed to the delete action"
controller.delete(address)
then:"The instance is deleted"
Address.count() == 0
response.redirectedUrl == '/address/index'
flash.message != null
}
}
/******************************** AddressController ******************************************/
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class AddressController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Address.list(params), model:[addressInstanceCount: Address.count()]
}
def show(Address addressInstance) {
respond addressInstance
}
def create() {
respond new Address(params)
}
@Transactional
def save(Address addressInstance) {
if (addressInstance == null) {
notFound()
return
}
if (addressInstance.hasErrors()) {
respond addressInstance.errors, view:'create'
return
}
addressInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'address.label', default: 'Address'), addressInstance.id])
redirect addressInstance
}
'*' { respond addressInstance, [status: CREATED] }
}
}
def edit(Address addressInstance) {
respond addressInstance
}
@Transactional
def update(Address addressInstance) {
if (addressInstance == null) {
notFound()
return
}
if (addressInstance.hasErrors()) {
respond addressInstance.errors, view:'edit'
return
}
addressInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'Address.label', default: 'Address'), addressInstance.id])
redirect addressInstance
}
'*'{ respond addressInstance, [status: OK] }
}
}
@Transactional
def delete(Address addressInstance) {
if (addressInstance == null) {
notFound()
return
}
addressInstance.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'Address.label', default: 'Address'), addressInstance.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'address.label', default: 'Address'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
更新
这似乎仅在 Intellij 中测试时才会发生。至少...从命令行运行时,7 个测试中只有 3 个失败。以下是命令行运行的结果:
test-app .AddressControllerSpec
| Running 2 unit tests... 3 of 3
| Failure: Test the save action correctly persists an instance(.AddressControllerSpec)
| Condition not satisfied:
model.addressInstance!= null
| | |
[:] null false
at .AddressControllerSpec.Test the save action correctly persists an instance(AddressControllerSpec.groovy:48)
| Running 2 unit tests... 6 of 6
| Failure: Test the update action performs an update on a valid domain instance(.AddressControllerSpec)
| Condition not satisfied:
response.redirectedUrl == '/address/index'
| | |
| null false
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@2906a2bf
at .AddressControllerSpec.Test the update action performs an update on a valid domain instance(AddressControllerSpec.groovy:102)
| Running 2 unit tests... 7 of 7
| Failure: Test that the delete action deletes an instance if it exists(.AddressControllerSpec)
| Condition not satisfied:
response.redirectedUrl == '/address/index'
| | |
| null false
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@590bd021
at .AddressControllerSpec.Test that the delete action deletes an instance if it exists(AddressControllerSpec.groovy:133)
| Completed 7 unit tests, 3 failed in 0m 6s
Configuring Spring Security Core ...
... finished configuring Spring Security Core
| Tests FAILED
在 Grails 2.4.0 中,我使用“grailsgenerate-all'*'”为我的应用程序生成脚手架。这也会创建 Controller 测试。然而,我相信这些 Controller 测试是错误的。就我而言,每次 7 次测试中有 6 次失败。这是一个损坏的示例:
@TestFor(AddressController)
@Mock(Address)
class AddressControllerSpec extends Specification {
.....
void "Test the create action returns the correct model"() {
when:"The create action is executed"
controller.create()
then:"The model is correctly created"
model.addressInstance != null
}
执行时失败,输出为:
Condition not satisfied:
model.addressInstance != null
| | |
| null false
[address:Address : (unsaved)]
at AddressControllerSpec.Test the create action returns the correct model(AddressControllerSpec.groovy:36)
请注意,模型本身是一个 Address 对象,但 addressInstance 为 null。
查看生成的 AddressController.groovy 中关联的 Controller 操作:
def create() {
respond new Address(params)
}
看看这没有设置一个名为 addressInstance 的变量,这难道不是测试失败的明显原因吗?我是 Grails 的新手(嗯,尝试用它做一些事情的新手),所以我不确定是否有一些本应在这里发挥作用的魔法,但事实并非如此,但事实上该模型确实是在我看来,设置为操作返回的对象表明存在错误。
有人可以在这里检查我的推理吗?我认为这段代码正确吗?
对我来说唯一通过的测试是:“测试索引操作返回正确的模型”
作为引用,这里是完整的 Controller 和测试代码:
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class AddressController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Address.list(params), model:[addressInstanceCount: Address.count()]
}
def show(Address addressInstance) {
respond addressInstance
}
def create() {
respond new Address(params)
}
@Transactional
def save(Address addressInstance) {
if (addressInstance == null) {
notFound()
return
}
if (addressInstance.hasErrors()) {
respond addressInstance.errors, view:'create'
return
}
addressInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'address.label', default: 'Address'), addressInstance.id])
redirect addressInstance
}
'*' { respond addressInstance, [status: CREATED] }
}
}
def edit(Address addressInstance) {
respond addressInstance
}
@Transactional
def update(Address addressInstance) {
if (addressInstance == null) {
notFound()
return
}
if (addressInstance.hasErrors()) {
respond addressInstance.errors, view:'edit'
return
}
addressInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'Address.label', default: 'Address'), addressInstance.id])
redirect addressInstance
}
'*'{ respond addressInstance, [status: OK] }
}
}
@Transactional
def delete(Address addressInstance) {
if (addressInstance == null) {
notFound()
return
}
addressInstance.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'Address.label', default: 'Address'), addressInstance.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'address.label', default: 'Address'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
/*********************************************************************************/
import grails.test.mixin.*
import spock.lang.*
@TestFor(AddressController)
@Mock(Address)
class AddressControllerSpec extends Specification {
def log = LogFactory.getLog(getClass())
def populateValidParams(params) {
assert params != null
// TODO: Populate valid properties like...
//params["name"] = 'someValidName'
}
void "Test the index action returns the correct model"() {
when:"The index action is executed"
controller.index()
then:"The model is correct"
!model.addressInstanceList
model.addressInstanceCount == 0
}
void "Test the create action returns the correct model"() {
when:"The create action is executed"
controller.create()
then:"The model is correctly created"
model.addressInstance != null
}
void "Test the save action correctly persists an instance"() {
when:"The save action is executed with an invalid instance"
request.contentType = FORM_CONTENT_TYPE
def address = new Address()
address.validate()
controller.save(address)
then:"The create view is rendered again with the correct model"
//model.addressInstance!= null
view == 'create'
when:"The save action is executed with a valid instance"
response.reset()
populateValidParams(params)
address = new Address(params)
controller.save(address)
then:"A redirect is issued to the show action"
response.redirectedUrl == '/address/show/1'
controller.flash.message != null
Address.count() == 1
}
void "Test that the show action returns the correct model"() {
when:"The show action is executed with a null domain"
controller.show(null)
then:"A 404 error is returned"
response.status == 404
when:"A domain instance is passed to the show action"
populateValidParams(params)
def address = new Address(params)
controller.show(address)
then:"A model is populated containing the domain instance"
model.addressInstance == address
}
void "Test that the edit action returns the correct model"() {
when:"The edit action is executed with a null domain"
controller.edit(null)
then:"A 404 error is returned"
response.status == 404
when:"A domain instance is passed to the edit action"
populateValidParams(params)
def address = new Address(params)
controller.edit(address)
then:"A model is populated containing the domain instance"
model.addressInstance == address
}
void "Test the update action performs an update on a valid domain instance"() {
when:"Update is called for a domain instance that doesn't exist"
request.contentType = FORM_CONTENT_TYPE
controller.update(null)
then:"A 404 error is returned"
response.redirectedUrl == '/address/index'
flash.message != null
when:"An invalid domain instance is passed to the update action"
response.reset()
def address = new Address()
address.validate()
controller.update(address)
then:"The edit view is rendered again with the invalid instance"
view == 'edit'
model.addressInstance == address
when:"A valid domain instance is passed to the update action"
response.reset()
populateValidParams(params)
address = new Address(params).save(flush: true)
controller.update(address)
then:"A redirect is issues to the show action"
response.redirectedUrl == "/address/show/$address.id"
flash.message != null
}
void "Test that the delete action deletes an instance if it exists"() {
when:"The delete action is called for a null instance"
request.contentType = FORM_CONTENT_TYPE
controller.delete(null)
then:"A 404 is returned"
response.redirectedUrl == '/address/index'
flash.message != null
when:"A domain instance is created"
response.reset()
populateValidParams(params)
def address = new Address(params).save(flush: true)
then:"It exists"
Address.count() == 1
when:"The domain instance is passed to the delete action"
controller.delete(address)
then:"The instance is deleted"
Address.count() == 0
response.redirectedUrl == '/address/index'
flash.message != null
}
}
最佳答案
测试受 allowedMethods 限制的 Controller 操作时,需要指定请求方法。
参见https://jira.grails.org/browse/GPSCAFFOLD-95
https://jira.grails.org/browse/GRAILS-8426
https://github.com/grails-plugins/grails-scaffolding/commit/db4eed57449e56225821ab565229b76bc394d2be
您可以将 BuildConfig.groovy 中的脚手架插件更新到版本 2.1.1,也可以手动更新生成的测试。
希望对您有所帮助。
关于grails generated-all '*' 创建损坏的 Controller 测试?脚手架生成是否已损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24071013/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!