I have a grails application with version 2.3.1 and the next configuration in BuildConfig.groovy
dependencies {
...
..
.
test "org.spockframework:spock-grails-support:0.7-groovy-2.0"
}
plugins {
test(":spock:0.7") {
exclude "spock-grails-support"
}
I have the next domain class:
class Draft {
def grailsApplication
String name
String subject
String content
static constraints = {
name unique: true, blank: false
subject blank: false
}
static mapping = {
content type: 'text'
}
}
I found this post Testing Domain Constraints Using Grails 2.x & Spock 0.7 with an interesting approach to test domain class constraints.
I have a spock test:
import spock.lang.Specification
abstract class ConstraintUnitSpec extends Specification {
String getLongString(Integer length) {
'a' * length
}
String getEmail(Boolean valid) {
valid ? "[email protected]" : "dexterm@m"
}
String getUrl(Boolean valid) {
valid ? "http://www.google.com" : "http:/ww.helloworld.com"
}
String getCreditCard(Boolean valid) {
valid ? "4111111111111111" : "41014"
}
void validateConstraints(obj, field, error) {
println "Draft name: " + obj.name
def validated = obj.validate()
if (error && error != 'valid') {
assert !validated
assert obj.errors[field]
assert error == obj.errors[field]
} else {
assert !obj.errors[field]
}
}
}
import grails.test.mixin.TestFor
import spock.lang.Unroll
@TestFor(Draft)
class DraftSpec extends ConstraintUnitSpec {
def setup() {
mockForConstraintsTests(Draft, [new Draft(name: 'unique')])
}
@Unroll("test draft all constraints #field is #error")
def "test draft all constraints"() {
when:
def obj = new Draft("$field": val)
then:
validateConstraints(obj, field, error)
where:
error | field | val
'nullable' | 'name' | null
'nullable' | 'subject' | null
'nullable' | 'content' | null
'unique' | 'name' | 'unique'
'valid' | 'name' | 'valid name'
'valid' | 'subject' | 'valid subject'
'blank' | 'name' | ''
'blank' | 'subject' | ''
}
}
Test fails in both blank
constraints:
Draft name: null
| Failure: test draft all constraints subject is blank(DraftSpec)
| Condition not satisfied:
error == obj.errors[field]
| | | | ||
blank | | | |subject
| | | nullable
| | org.codehaus.groovy.grails.plugins.testing.GrailsMockErrors: 3 errors
| | Field error in object 'Draft' on field 'name': rejected value [null]; codes [Draft.name.nullable.error.Draft.name,Draft.name.nullable.error.name,Draft.name.nullable.error.java.lang.String,Draft.name.nullable.error,draft.name.nullable.error.Draft.name,draft.name.nullable.error.name,draft.name.nullable.error.java.lang.String,draft.name.nullable.error,Draft.name.nullable.Draft.name,Draft.name.nullable.name,Draft.name.nullable.java.lang.String,Draft.name.nullable,draft.name.nullable.Draft.name,draft.name.nullable.name,draft.name.nullable.java.lang.String,draft.name.nullable,nullable.Draft.name,nullable.name,nullable.java.lang.String,nullable]; arguments [name,class Draft]; default message [Property [{0}] of class [{1}] cannot be null]
| | Field error in object 'Draft' on field 'subject': rejected value [null]; codes [Draft.subject.nullable.error.Draft.subject,Draft.subject.nullable.error.subject,Draft.subject.nullable.error.java.lang.String,Draft.subject.nullable.error,draft.subject.nullable.error.Draft.subject,draft.subject.nullable.error.subject,draft.subject.nullable.error.java.lang.String,draft.subject.nullable.error,Draft.subject.nullable.Draft.subject,Draft.subject.nullable.subject,Draft.subject.nullable.java.lang.String,Draft.subject.nullable,draft.subject.nullable.Draft.subject,draft.subject.nullable.subject,draft.subject.nullable.java.lang.String,draft.subject.nullable,nullable.Draft.subject,nullable.subject,nullable.java.lang.String,nullable]; arguments [subject,class Draft]; default message [Property [{0}] of class [{1}] cannot be null]
| | Field error in object 'Draft' on field 'content': rejected value [null]; codes [Draft.content.nullable.error.Draft.content,Draft.content.nullable.error.content,Draft.content.nullable.error.java.lang.String,Draft.content.nullable.error,draft.content.nullable.error.Draft.content,draft.content.nullable.error.content,draft.content.nullable.error.java.lang.String,draft.content.nullable.error,Draft.content.nullable.Draft.content,Draft.content.nullable.content,Draft.content.nullable.java.lang.String,Draft.content.nullable,draft.content.nullable.Draft.content,draft.content.nullable.content,draft.content.nullable.java.lang.String,draft.content.nullable,nullable.Draft.content,nullable.content,nullable.java.lang.String,nullable]; arguments [content,class Draft]; default message [Property [{0}] of class [{1}] cannot be null]
| Draft : (unsaved)
false
6 differences (25% similarity)
(b-)l(-)a(nk-)
(nu)l(l)a(ble)
at ConstraintUnitSpec.validateConstraints(ConstraintUnitSpec.groovy:29)
at DraftSpec.test draft all constraints(DraftSpec.groovy:18)
| Completed 8 spock tests, 2 failed in 0m 6s
| Tests FAILED - view reports in /Users/sdelamo/Documents/Developer/bitbucket/concertados-webapp/target/test-reports
Draft
's name
field is set as null when I pass ''
as value
What am I missing?. Thanks in advance.
def "test blank constraints"() {
when: 'the name and subjects are blank'
def d = new Draft(name: '', subject:'')
then: 'the validation should fail with blank errors'
!d.validate()
'blank' == d.errors["name"]
'blank' == d.errors["subject"]
}
This is the error:
| Running 1 spock test... 1 of 1
--Output from test blank constraints--
| Error --Output from test blank constraints--
| Failure: test blank constraints(com.softamo.concertados.DraftSpec)
| Condition not satisfied:
'blank' == d.errors["name"]
| | | |
| | | nullable
| | org.codehaus.groovy.grails.plugins.testing.GrailsMockErrors: 3 errors
Time_yates pointed to the issue:
http://grails.org/doc/latest/ref/Constraints/nullable.html
Web requests resulting from form submissions will have blank strings, not null, for input fields that have no value. Keep this in mind when doing mass property binding to properties that are not nullable. The default behavior is such that a blank string will not validate for nullable: false since the data binder will convert blank strings to null. This includes empty strings and blank strings. A blank string is any string such that the trim() method returns an empty string. To turn off the conversion of empty strings to null set the grails.databinding.convertEmptyStringsToNull property to false in Config.groovy. See the data binding section for more details on data binding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With