简体   繁体   中英

Grails Unique Id constraint in Unit test not failing

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)
    }
}

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()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM