【问题标题】:Grails Domain Class Unit Test, issue with Constraint setup - java.lang.NoClassDefFoundError: Could not initializeGrails 域类单元测试,约束设置问题 - java.lang.NoClassDefFoundError:无法初始化
【发布时间】:2014-01-14 13:45:27
【问题描述】:

我对域类的 grails 单元测试抛出了这个异常:

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

以下是我精简的域类:

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

我的 com.pkg.common.Configuration 类只是一个具有静态属性的单例:

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" 是在 application.properties 中定义的 RegEx:

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

现在,为什么仅仅设置一个约束就这么痛苦?好吧,我需要在我的 15 多个域中保留所有文本字段,在他们接受的字符方面保持一致。由于这是业务驱动的需求,我需要保持它是可配置的,以便我们可以随时删除/添加任何新字符,而不会有为了完整性而接触太多域类的风险。除此之外,我还想在其他服务类中使用可用的正则表达式。

现在,此实现在运行应用、生产和测试应用集成中运行良好: 唯一的问题是单元测试用例。我能理解的是,这样的依赖关系,Grails 将无法在单元测试环境中自动注入。

我们可以使用元类操作来模拟和添加配置类吗?我试过但失败了。(阅读:我不知道静态类的模拟如何工作以及如何将它们添加到元类)

或者,如果有另一种方式来实现这种概念?

很多

【问题讨论】:

  • 包是保留字
  • 您应该将allowed.text.chars 放入Config.groovy 而不是application.properties 并使用grailsApplication.config.allowed.text.chars 阅读它
  • @moskiteau :我放了“包”这个词只是为了提出这个问题:P .. 我的坏.. 应该更新相同

标签: regex unit-testing grails grails-orm grails-domain-class


【解决方案1】:

为避免跨多个域类重复约束,您可以使用shared constraint or a global constraint

如果您使用全局约束,那么为了使您能够从服务类访问正则表达式,请将正则表达式存储在单独的配置参数中。

Config.groovy

​​>
allowed.text.chars='bigLongRegex'

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

服务类

class MyService {

   GrailsApplication grailsApplication

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

如果你想编写一个单元测试来测试域类的约束,记得添加@Mock注解,例如

@Mock([DomainClass])
class DomainClassTests {
   void testConstraint() {
     // test code goes here
   }
}

【讨论】:

  • 非常感谢全局约束的提示:) ...我之前完全跳过阅读。
  • 虽然,将 Regex 移动到 Configuration.groovy 解决了所有问题,但我会按照建议使用全局约束,因为这样我什至不需要另一个 Singleton。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
  • 2018-09-12
  • 1970-01-01
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多