How can I implement Groovy's new traits in my Grails Spock tests? Every time I try, I get a stacktrace that looks like this. Is there some limitation of Groovy trails that I might not be aware of?
JDK Version:
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 Version:
Grails version: 2.4.3
Simplified Code:
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
}
}
Stacktrace:
[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)
The same exception occurs in our project which makes heavy use of traits:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
My colleague found out that this happens as soon as a trait has more than 10 fields. The origin of this behavior is unknown to us.
As a workaround we make use of trait inheritance:
trait Foo extends MoreFoo {
//this has 10 fields
}
trait MoreFoo{
//this has some more fields but not more than 10
}
It is noteworthy that we use Groovy on Android so adjusting JVM options as proposed by ColimMc is not an option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With