当前位置: 首页 > 知识库问答 >
问题:

在Grails测试中使用Groovy特性失败

逑兴安
2023-03-14

我如何在我的Grails Spock测试中实现Groovy的新特性?每次我尝试,我都会得到一个看起来像这样的堆栈跟踪。Groovy路径是否有一些我可能不知道的限制?

JDK 版本:

java version "1.7.0_65"
OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)

Groovy Verison:

Groovy Version: 2.3.6 JVM: 1.7.0_65 Vendor: Oracle Corporation OS: Linux

Grails版本:

Grails version: 2.4.3

简化代码:

import grails.test.mixin.Mock
@Mock([AnalyticFilters])
trait ControllerTestBase {
public void setupCommonStuff(boolean setupIdCall = false) {
params.devId = TEST_DEV_ID
    // mocking version filter
    params.version = "v${TEST_VERSION}"

    defineBeans{
       CacheService(cacheServiceMock: "createMock")
    }

    CommonParams.parseParams(params)

    cacheMock = applicationContext.getBean("cacheServiceMock")

    if(setupStoreIdCall) {
        cacheMock.demandExplicit.makeCompositeKey(0..20) { List<String> list ->
            def (String uuid, String orgUuid) = list
            return "foobar"
        }
    }

}
}

@TestFor(AuditController)
public class AuditControllerSpecs extends Specification implements ControllerTestBase {

private def auditServiceFactory

public String testAuditData = "{audit:'whatever'}"

public void setup() {
    setupCommonParams()

    defineBeans {
        auditServiceFactory(GrailsMock, AuditService)
        auditService(auditServiceFactory: "createMock")
    }
    auditServiceFactory = applicationContext.getBean("auditServiceFactory")
    auditServiceFactory.demand.writeEventToMongo { BasicDBObject data -> }
    controller.auditService = applicationContext.getBean('auditService', AuditService)
}

def "calling productAudit should return with 200 and OK"() {

    given:
    request.JSON = JSON.parse(testAuditData)
    request.method = 'POST'
    when:
    withFilters(action: "productAudit") {
        controller.productAudit()
    }
    then:

    def res = JSON.parse(response.text)

    expect:
    response.status == 200
    res.message == "OK"
    100 == 2
}

}

堆栈跟踪:

 [groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
  [groovyc] General error during canonicalization: Comparison method violates its general contract!
  [groovyc] 
  [groovyc] java.lang.IllegalArgumentException: Comparison method violates its general contract!
  [groovyc]     at java.util.TimSort.mergeLo(TimSort.java:747)
  [groovyc]     at java.util.TimSort.mergeAt(TimSort.java:483)
  [groovyc]     at java.util.TimSort.mergeCollapse(TimSort.java:410)
  [groovyc]     at java.util.TimSort.sort(TimSort.java:214)
  [groovyc]     at java.util.TimSort.sort(TimSort.java:173)
  [groovyc]     at java.util.Arrays.sort(Arrays.java:659)
  [groovyc]     at java.util.Collections.sort(Collections.java:217)
  [groovyc]     at org.codehaus.groovy.transform.trait.TraitComposer.applyTrait(TraitComposer.java:183)
  [groovyc]     at org.codehaus.groovy.transform.trait.TraitComposer.doExtendTraits(TraitComposer.java:105)
  [groovyc]     at org.codehaus.groovy.control.CompilationUnit$4.call(CompilationUnit.java:188)
  [groovyc]     at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1047)
  [groovyc]     at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:583)
  [groovyc]     at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:561)
  [groovyc]     at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:538)
  [groovyc]     at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:517)
  [groovyc]     at org.codehaus.groovy.tools.FileSystemCompiler.compile(FileSystemCompiler.java:59)
  [groovyc]     at org.codehaus.groovy.tools.FileSystemCompiler.doCompilation(FileSystemCompiler.java:215)
  [groovyc]     at org.codehaus.groovy.ant.Groovyc.runCompiler(Groovyc.java:1104)
  [groovyc]     at org.codehaus.groovy.ant.Groovyc.compile(Groovyc.java:1155)
  [groovyc]     at org.codehaus.groovy.grails.compiler.Grailsc.compile(Grailsc.java:78)
  [groovyc]     at org.codehaus.groovy.ant.Groovyc.execute(Groovyc.java:770)
  [groovyc]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
  [groovyc]     at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
  [groovyc]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  [groovyc]     at java.lang.reflect.Method.invoke(Method.java:606)
  [groovyc]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
  [groovyc]     at groovy.util.AntBuilder.performTask(AntBuilder.java:319)
  [groovyc]     at groovy.util.AntBuilder.nodeCompleted(AntBuilder.java:264)
  [groovyc]     at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
  [groovyc]     at groovy.util.AntBuilder.doInvokeMethod(AntBuilder.java:203)
  [groovyc]     at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:64)

共有2个答案

庞瀚
2023-03-14

在我看来,使用特征的脚本字段存在限制。如果使用特征的实现中的字段数达到一定大小(我的情况为 34 个方法),则抛出此异常。我目前遇到了与您相同的问题,我正在尝试解决它。

我可以通过使用以下代码来使用Groovy:

-Djava.util.Arrays.useLegacyMergeSort=true

如下所述: https://stackoverflow.com/a/13575810/1673785

我认为这与他们的GETTER_FIRST_COMPARATOR比较器有关,它不返回0。它只返回1和-1,我认为这是它提到违反合同的原因。

江敏学
2023-03-14

在我们的项目中也出现了同样的例外,它大量使用了特征:

java.lang.IllegalArgumentException:比较方法违反了它的一般约定

我的同事发现,当一个特征有超过10个字段时,就会发生这种情况。我们不知道这种行为的起源。

作为一种变通方法,我们利用特征继承:

trait Foo extends MoreFoo {
    //this has 10 fields
}

trait MoreFoo{
    //this has some more fields but not more than 10
}

值得注意的是,我们在Android上使用Groovy,因此ColimMc建议的调整JVM选项不是一个选项。

 类似资料:
  • 我想在Grails控制器中使用Groovy特性,如下所示: 然而,当我在Grails中运行此操作时,“selectColumns”操作不可见,我从Grails得到了404响应。我怀疑我需要对trait做些什么,以便它内部定义的方法在实现类中被识别为动作。有人知道这可能是什么吗? 编辑1: 更多信息:trait是在src/Groovy中定义的,而不是在grails-app/控制器中定义的,因此它没有

  • 我在 Groovy 控制台中测试了以下代码,两者都按预期失败:第一个测试: 第二个测试: 等价物在Grails中运行(即类被实例化并在单元测试中使用),但不会抛出异常。例如: 我可以知道为什么会有差异吗?谢谢。

  • 我开发了一套关于实体的保存、搜索和修改的Spock测试,一切都运行得很顺利。具体地说,我有一个Spring Boot应用程序冒烟测试,以确保配置正确加载 由于自然密钥是channel和service,所以我尝试定义了一个复合密钥 以及主键类(节选) 构建jar并运行测试,然后 启动Spring Boot服务器

  • 我有一个groovy脚本,它通过使用readline方法的java.io.Console对象向用户提问。另外,我用它来询问密码(用于设置HTTPS)。如何使用Spock对此代码进行单元测试?目前,它抱怨该对象是Java final对象,无法测试。显然,我不是第一个尝试这个的人,所以我想我会问。 代码的草图如下所示: 我希望单元测试来测试一些模拟响应可以返回,默认值可以返回。注意:这是简化的,这样我

  • 我有一个文件夹结构如下 当我运行命令时。它只运行Java单元测试(位于*src\test\Java*目录下),而不调用Groovy测试用例。Groovy似乎再也找不到Groovy测试了。 请帮助我在Maven的帮助下启用groovy测试用例执行? 波姆。xml