Using grails configuration values in domain object constraints - unit-testing

Grails 2.2.0
How do I access the custom configuration variables in a Grails domain object constraints.
I would like to have something like this:
class User {
def grailsApplication
String name
static constraints = {
name size: grailsApplication.config.maxlength
}
}
But it fails with "No such property: grailsApplication". I have tried to get it work by following suggestions in getting grails 2.0.0M1 config info in domain object, and static scope? but have not managed to get any combination to work.
How do I access config in domain object constraints? In addition how do I handle such a case in a unit test for the domain constraints?

You can use the grails.util.Holders class to get access to the configuration object as follows:
In Config.groovy:
myMaxSize = 10
In your domain class:
class User {
String name
static constraints = {
name minSize: Holders.config.myMaxSize
}
}

Related

grails domain class not mocked

I'm trying to mock the Role class generated by shiro plugin in a Grails 2.2.1 app. When i'm runnint the unit test I'm getting this error that looks like the dynamics method are not added.
This is the Role class:
class Role {
String name
static hasMany = [ users: User, permissions: String ]
static belongsTo = User
static constraints = {
name nullable: false, blank: false, unique: true
}
}
and this is the unit test:
#TestFor(UserService)
#TestMixin(DomainClassUnitTestMixin)
#Mock([User, Role])
class UserServiceTests {
void testSaveFacebookUser(){
//given
def adminRole = new Role(name: RoleEnum.ADMIN.name)
adminRole.addToPermissions("*:*")
adminRole.save()
}
}
The stacktrace:
Running 1 unit test... 1 of 1
Failure: testSaveFacebookUser(a4o.services.UserServiceTests)
groovy.lang.MissingMethodException: No signature of method: a4o.Role.addToPermissions() is applicable
for argument types: (java.lang.String) values: [*:*]
UPDATE
found this on JIRA, but it says it was closed for 2.0.4 http://jira.grails.org/browse/GRAILS-8779 . Maybe it's open again.
AFAIK, the hasMany statement is supposed to be used to connect the given class with other Grails domain classes, not with other object. If you need to save a list of permissions as String objects, you need to create (and handle!) that list of strings outside the hasMany block; something like this:
class Role {
String name
List<String> permissions
static hasMany = [ users: User ]
static belongsTo = User
static constraints = {
name nullable: false, blank: false, unique: true
}
}
Anyways, my suggestion is not to reinvent the wheel and use the sprint security plugin (or another one of your choice).
upgrading to grails 2.2.2 solved this issue

#Mock domain objects in unit testing in grails listOrderBy dynamic finder throws an exception

I am writing a unit test for a grails controller. Here is a snippet of the code:
#TestFor(MyController)
#Mock([MyDomain])
class MyControllerTests {
void testController() {
...
...
}
}
Here is how the domain object looks like:
class MyDomain {
static constraints = {
name(nullable: false)
parent(nullable: true)
}
static belongsTo = Industry
static hasMany = [children: Industry]
Industry parent
String name
}
The method in the controller I am testing calls this GORM dynamic method:
MyDomain.listOrderByParent()
The test fails when execution hits this line and the exception is not making much sense to me since the #Mock annotation should have added all the dynamic methods:
groovy.lang.GroovyRuntimeException: Cannot compare com.stuff.MyDomain with value 'com.stuff.MyDomain : 1' and com.stuff.MyDomain with value 'com.stuff.MyDomain : 4'
at org.grails.datastore.mapping.simple.query.SimpleMapQuery$_executeQuery_closure63_closure155.doCall(SimpleMapQuery.groovy:78)
The controller works fine when running the grails app. Any ideas?
You may mock the Industry domain object
as well:
#Mock([MyDomain, Industry])

grails/groovy: How do I access saved domain objects when unit testing?

I'm trying to get access to saved domain objects during unit testing, so when a controller method saves a domain class outside the scope of the unit test i can access it to test the properties set on it.
have been looking at the domainClassesInfo (DefaultArtefactInfo), savedMetaClasses from interrogating this, but without success.
This seems like something that should be easy -
void testMyControllerMethod() {
mockDomain(MyDomainClass)
controller.myControllerMethod()
//get MyDomainClass instance here for test assertions
//assertEquals value1, myDomainClass.attribute1
}
then in the controller:
def MyControllerMethod() {
//do stuff
MyDomainClass myDomainClass = new MyDomainClass(attribute1:value1,attribute2:value2)
myDomainClass.save()
}
Any thoughts how to extract the saved domain class much appreciated
IF the controller is the only one saving a new instance of MyDomainClass then you should be able to do this:
void testMyControllerMethod() {
mockDomain(MyDomainClass)
controller.myControllerMethod()
//get MyDomainClass instance here for test assertions
def result = MyDomainClass.list()[0]
assertEquals value1, result.attribute1
}

Mocking the "save" method on domain classes

I'm having hard time mocking the save instance method in my unit tests in Grails 1.3.3. I've created a simple domain class named Person, it has one property (nullable) called "name".
package tutorial
class Person {
String name
static constraints = {
name nullable: true
}
}
In my test I'm trying to do something I've found in the documentation:
class PersonTests extends GrailsUnitTestCase {
public void testCanSavePerson() {
def testInstances = []
mockDomain(Person, testInstances)
assertEquals(0, Person.count())
new Person(name: "Bob").save()
assertEquals(1, Person.count())
}
}
However as soon as I run the test what I get is an exception:
java.lang.NullPointerException
at grails.test.MockUtils$_addValidateMethod_closure83.doCall(MockUtils.groovy:973)
at grails.test.MockUtils$_addValidateMethod_closure84.doCall(MockUtils.groovy:1014)
at grails.test.MockUtils$_addDynamicInstanceMethods_closure67.doCall(MockUtils.groovy:736)
at grails.test.MockUtils$_addDynamicInstanceMethods_closure67.doCall(MockUtils.groovy)
at tutorial.PersonTests.testCanSavePerson(PersonTests.groovy:25)
whereas the line 25 is exactly the one that calls save() on newly created instance.
Does anyone knows what am I doing wrong?
This is an already known bug in Grails 1.3.3. Read more about it and find a workaround in the associated JIRA ticket GRAILS-6482.

Testing custom constraints in Grails App

I have the following as my unit test:
void testCreateDealer() {
mockForConstraintsTests(Dealer)
def _dealer= new Dealer( dealerName:"ABC",
Email:"abc-motors#global.com",
HeadOffice:"",
isBranch:false)
assertFalse _dealer.validate()
}
But when I run the test I get the following error:
No signature of method: static com.myCompany.Dealer.findByDealerNameIlike() is applicable for argument types: (java.lang.String) values: [ABC]
I use some custom constraints in my domain class. How Can I test this?
static constraints = {
dealerName(blank:false, validator:
{ val, obj ->
def similarDealer = Dealer.findByDealerNameIlike(val)
return !similarDealer || (obj.id == similarDealer.id)
}
)
Try changing mockForConstraintsTests() to mockDomain() - you're using a Dealer.findX() method in the constraint, which relies on the Dealer domain.
Incidentally, the test will still fail unless you've created a similar dealer in the setUp() method of the test class.
In unit tests, even with mockDomain, the id attribute of domain objects is not set automatically, or auto-incremented. All of the domain objects you create will have an id of null unless you explicitly set it.
Your test is probably failing because the test obj.id == similarDealer.id is true, since they both have id: null. Try setting the id attribute of your mocked dealer objects.