Reputation: 1463
I'm upgrading from grails 1.3.6 to 2.2.4 and going through all of my unit tests. I have been replacing mockDomain with the @Mock annotation among other things. One of my tests is validating that IDs remain unique and fail if an id already exists. This no longer seems to be failing as expected. The test is as follows:
import grails.test.*
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
@Mock(SecurityValue)
@TestFor(SecurityValue)
class SecurityValueTests{
void testUniqueId() {
def validEntry = new SecurityValue(id:"id",propertyName:"propertyName",userId:"testUser",componentId:1000)
validEntry.id = "id"
def saved = validEntry.save(flush:true, failOnError:true)
assertNotNull saved
def validEntry2 = new SecurityValue(id:"id",propertyName:"propertyName1",userId:"testUser3")
validEntry2.id = "id"
def saved2 = validEntry2.save(flush:true, failOnError:true)
def all = SecurityValue.findAll()
assertNull saved
}
}
Domain:
class SecurityValue {
String id
String propertyName
String userId
//String userName
Long componentId
static constraints =
{
id unique:true, size: 1..100
propertyName nullable: false, size: 1..100
userId nullable: false, size: 1..10
componentId (
nullable: true, size: 1..10
)
}
static mapping =
{
table 'pac_sys.security_value'
id column:'id', type: 'string', generator: 'assigned'
version false;
}
}
The issue I'm getting is that the validEntry2.save
line is not failing. I added the findAll
line to see what data was being stored and it appears that the validEntry
is just being overwritten by validEntry2
.
Am I missing a mock statement or something else here?
Here is what the test look slike after applying jonnybot's answer. It now has a shouldFail method rather than an assertNull and works properly.
void testUniqueId() {
def validEntry = new SecurityValue(id:"id",propertyName:"propertyName",userId:"testUser",componentId:1000)
validEntry.id = "id"
mockForConstraintsTests(SecurityValue, [validEntry])
def validEntry2 = new SecurityValue(id:"id",propertyName:"propertyName1",userId:"testUser3")
validEntry2.id = "id"
shouldFail(grails.validation.ValidationException)
{
def saved2 = validEntry2.save(flush:true, failOnError:true)
}
}
Upvotes: 3
Views: 1300
Reputation: 2453
Since what you really want to do is test the constraints, use the mockForConstraintsTests() and validate() methods in your test. See "Testing Constraints" under http://grails.org/doc/2.2.4/guide/testing.html#unitTestingDomains.
For example, you might have
void testUniqueId() {
def validEntry = new SecurityValue(id:"id",propertyName:"propertyName",userId:"testUser",componentId:1000)
validEntry.id = "id"
def saved = validEntry.save(flush:true, failOnError:true)
assertNotNull saved
mockForConstraintsTests(SecurityValue, [validEntry])
def invalidEntry = new SecurityValue(id:"id",propertyName:"propertyName1",userId:"testUser3")
invalidEntry.id = "id"
assert !invalidEntry.validate()
}
Upvotes: 4