Grails 4:如何禁用域对象的深度验证以进行测试
Grails 4: How to Disable Deep Validation of Domain Objects for Testing
我正在迁移 Grails 2.4.4。应用;我的一些执行域对象验证的服务方法未通过测试,因为验证级联到关联。例如,
测试方法
class AdditionalPhotoServiceSpec extends HibernateSpec implements ServiceUnitTest<AdditionalPhotoService>, DataTest {
Person person
AdditionalPhotoType additionalPhotoType
S3Service mockS3Service
def setup() {
[Person, AdditionalPhotoType, AdditionalPhoto, Organization].each { mockDomain(it) }
person = new Person().save(validate: false)
additionalPhotoType = new AdditionalPhotoType().save(validate: false)
mockS3Service = Mock()
service.s3Service = mockS3Service
}
def cleanup() {
}
def "create additional photo"() {
when:
assert person.organization.id
AdditionalPhoto additionalPhoto = service.create(new AdditionalPhoto(person: person, additionalPhotoType: additionalPhotoType, bytes: [1, 2, 3]))
then:
additionalPhoto?.id
and:
1 * mockS3Service.storePhoto(testAdditionalPhoto())
}
这试图创建一个 AdditionalPhoto
,其中包含两个已使用 validate: false
保存的关联对象。
正在测试的服务方法
class AdditionalPhotoService {
S3Service s3Service
boolean enableDeleteAllForDownloadedPhotos = false
AdditionalPhoto create(AdditionalPhoto additionalPhoto) {
additionalPhoto.validate()
if (additionalPhoto.hasErrors())
throw new InvalidResourceException(additionalPhoto.errors)
deletePriorAdditionalPhotos(additionalPhoto)
additionalPhoto.save()
additionalPhoto.externalURL = s3Service.storePhoto(additionalPhoto)
return additionalPhoto
}
}
问题
测试失败,因为服务方法中的 additionalPhoto.validate()
正在验证关联对象 Person
和 AdditionalPhotoType
,而不仅仅是 AdditionalPhoto
。对于生产,我喜欢这种行为,但我不想对测试进行深入验证,因为它需要我创建与 Person
和 AdditionalPhotoType
及其关联以及它们的关联关联的所有域对象等。它似乎会创建冗长、脆弱的测试代码。
问题
如何在不更改生产代码的情况下仅针对测试禁用域对象的深度验证?
我已经看过的东西
- how to disable deepvalidate in grails globally?
- How to make cascade to false for all grails domains at global level
事实证明,这两个问题几乎都是我需要的。
我创建了以下 application.groovy
文件。
grails-app/conf/application.groovy
environments {
test {
grails.gorm.default.mapping = {
'*' cascade:'none'
}
}
}
我正在迁移 Grails 2.4.4。应用;我的一些执行域对象验证的服务方法未通过测试,因为验证级联到关联。例如,
测试方法
class AdditionalPhotoServiceSpec extends HibernateSpec implements ServiceUnitTest<AdditionalPhotoService>, DataTest {
Person person
AdditionalPhotoType additionalPhotoType
S3Service mockS3Service
def setup() {
[Person, AdditionalPhotoType, AdditionalPhoto, Organization].each { mockDomain(it) }
person = new Person().save(validate: false)
additionalPhotoType = new AdditionalPhotoType().save(validate: false)
mockS3Service = Mock()
service.s3Service = mockS3Service
}
def cleanup() {
}
def "create additional photo"() {
when:
assert person.organization.id
AdditionalPhoto additionalPhoto = service.create(new AdditionalPhoto(person: person, additionalPhotoType: additionalPhotoType, bytes: [1, 2, 3]))
then:
additionalPhoto?.id
and:
1 * mockS3Service.storePhoto(testAdditionalPhoto())
}
这试图创建一个 AdditionalPhoto
,其中包含两个已使用 validate: false
保存的关联对象。
正在测试的服务方法
class AdditionalPhotoService {
S3Service s3Service
boolean enableDeleteAllForDownloadedPhotos = false
AdditionalPhoto create(AdditionalPhoto additionalPhoto) {
additionalPhoto.validate()
if (additionalPhoto.hasErrors())
throw new InvalidResourceException(additionalPhoto.errors)
deletePriorAdditionalPhotos(additionalPhoto)
additionalPhoto.save()
additionalPhoto.externalURL = s3Service.storePhoto(additionalPhoto)
return additionalPhoto
}
}
问题
测试失败,因为服务方法中的 additionalPhoto.validate()
正在验证关联对象 Person
和 AdditionalPhotoType
,而不仅仅是 AdditionalPhoto
。对于生产,我喜欢这种行为,但我不想对测试进行深入验证,因为它需要我创建与 Person
和 AdditionalPhotoType
及其关联以及它们的关联关联的所有域对象等。它似乎会创建冗长、脆弱的测试代码。
问题
如何在不更改生产代码的情况下仅针对测试禁用域对象的深度验证?
我已经看过的东西
- how to disable deepvalidate in grails globally?
- How to make cascade to false for all grails domains at global level
事实证明,这两个问题几乎都是我需要的。
我创建了以下 application.groovy
文件。
grails-app/conf/application.groovy
environments {
test {
grails.gorm.default.mapping = {
'*' cascade:'none'
}
}
}