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
Problem
Draft
's name
field is set as null when I pass ''
as value
What am I missing?. Thanks in advance.
SIMPLE TEST fails as well
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
def obj = new Draft(subject:'')
, and it's failing becausename
is null? – Brickle''
on the last test in the table'blank' | 'subject' | ''
– Bricklenullable
have a pull out block about Grails converting''
tonull
by default: "...the data binder will convert blank strings to null" – Brickle