Grails Domain Class Unit Test, issue with Constraint setup - java.lang.NoClassDefFoundError: Could not initialize

StackOverflow https://stackoverflow.com/questions/21115085

Domanda

My grails unit test for domain class is throwing this exception:

|  java.lang.NoClassDefFoundError: Could not initialize class com.pkg.common.Configuration
    at com.pkg.DomainClass$__clinit__closure1.doCall(DomainClass.groovy:10)
    at org.grails.datastore.mapping.config.groovy.MappingConfigurationBuilder.evaluate(MappingConfigurationBuilder.groovy:72)
    at org.grails.datastore.mapping.config.AbstractGormMappingFactory.createMappedForm(AbstractGormMappingFactory.java:51)
    at org.grails.datastore.mapping.keyvalue.mapping.config.GormKeyValueMappingFactory.createMappedForm(GormKeyValueMappingFactory.java:37)
    at org.grails.datastore.mapping.keyvalue.mapping.config.GormKeyValueMappingFactory.createMappedForm(GormKeyValueMappingFactory.java:27)
    at org.grails.datastore.mapping.keyvalue.mapping.config.KeyValuePersistentEntity.<init>(KeyValuePersistentEntity.java:33)
    at org.grails.datastore.mapping.keyvalue.mapping.config.KeyValueMappingContext.createPersistentEntity(KeyValueMappingContext.java:89)
    at org.grails.datastore.mapping.model.AbstractMappingContext.addPersistentEntityInternal(AbstractMappingContext.java:159)
    at org.grails.datastore.mapping.model.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:152)
    at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomain(DomainClassUnitTestMixin.groovy:133)
    at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomain(DomainClassUnitTestMixin.groovy:129)

Following is my stripped down Domain class :

package com.pkg

import com.pkg.common.Configuration

class DomainClass {

    String subject

    static constraints = {
        subject(maxSize: 100, nullable: false, blank: false, matches: Configuration.ALLOWED_TEXT_CHARS)
    }
}

My com.pkg.common.Configuration class is just a Singleton with static properties :

package com.pkg.common

import grails.util.Holders

class Configuration{
    final public static String ALLOWED_TEXT_CHARS = "${Holders.grailsApplication.metadata["allowed.text.chars"]}"
}

"allowed.text.chars" is a RegEx defined in application.properties :

allowed.text.chars=[a-zA-Z0-9\\p{L}\\p{Digit}_"` $ \\-'_&;\:#()/\\.,!\\?%*|<>]+

Now, why this much pain just to set up a constraint ? Well, I need to keep all text fields across my 15+ domains, consistent in terms of characters they accept. Since this is business driven requirement, I need to keep it configurable, so that we can remove/add any new chars at any time, without the risk of touching too many domain classes for the sake of integrity. In addition to that, I want to use the available regex in other Service classes as well.

Now, this implementation works well in run-app, production & test-app integration: Only problem is with Unit tests cases. What I can understand is, that such dependencies, Grails won't be able to inject automatically, in a unit-test env.

Can we mock & add Configuration class using metaClass manipulation ? I have tried but failed.(read: I am not aware how mocking for Static classes work and how to add them to metaClass)

Or, if there's another way to implement such kind of concept ?

Many Thnx

È stato utile?

Soluzione

To avoid repeating the constraint across multiple domain classes, you could use either a shared constraint or a global constraint.

If you use a global constraint, then to enable you to access the regex from a service class, store the regex in a separate config param.

Config.groovy

allowed.text.chars='bigLongRegex'

grails.gorm.default.constraints = {
    subject matches: allowed.text.chars
}

Service Class

class MyService {

   GrailsApplication grailsApplication

   void something() {
      String regex = grailsApplication.config.allowed.text.chars
   }
}

If you want to write a unit test that tests the domain class' constraint remember to add the @Mock annotation, e.g.

@Mock([DomainClass])
class DomainClassTests {
   void testConstraint() {
     // test code goes here
   }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top