2014-12-02 7 views
6

Come posso implementare i nuovi tratti di Groovy nei test Grails Spock? Ogni volta che provo, ottengo uno stacktrace che assomiglia a questo. C'è qualche limite di percorsi Groovy di cui potrei non essere a conoscenza?Utilizzo di Groovy Trait in Grails Test non è riuscito

JDK Versione:

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 Versione:

Grails version: 2.4.3 

codice semplificato:

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

Dipende da come viene utilizzato. puoi aggiungere cosa stai facendo? – dmahapatro

+0

Puoi dirmi quale versione di JVM usi? – melix

risposta

-1

Mi sembra che ci sia un limite con campi di script che utilizzano i tratti. Se il numero di campi dall'implementazione che utilizza un tratto raggiunge una certa dimensione (i miei metodi del caso 34), viene generata questa eccezione. Attualmente sto incontrando questo stesso problema che hai e sto cercando di risolverlo.

sono stato in grado di aggirare Groovy utilizzando:

-Djava.util.Arrays.useLegacyMergeSort=true 

come accennato qui: https://stackoverflow.com/a/13575810/1673785

Io penso che abbia a che fare con il loro comparatore GETTER_FIRST_COMPARATOR dove non restituisce 0. solo restituisce 1 e -1, che ritengo sia la ragione per cui menziona una violazione del contratto.

8

La stessa eccezione si verifica nel nostro progetto, che fa un uso pesante di tratti:

java.lang.IllegalArgumentException: Comparison method violates its general contract!

Il mio collega ha scoperto che questo accade, non appena un tratto ha più di 10 campi. L'origine di questo comportamento ci è sconosciuta.

Come soluzione alternativa si fanno uso di eredità tratto:

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

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

È interessante notare che usiamo Groovy su Android in modo da regolare le opzioni JVM come proposto dal ColimMc non è un'opzione.

+1

ha avuto il problema con 10 campi in tratto, rimosso uno e tutto era di nuovo normale, la cosa interessante era tutto ok finché non ho riavviato il computer – tomasb

+1

Basta inserire lo stesso errore del compilatore ambiguo con un tratto con 10+ campi - abbassando il numero in < 10 risolto - che strano errore (compilatore Groovy-Eclipse 2.9.2-01, groovy-all 2.4.9 –

+0

@TomBunting Sono lieto che tu abbia trovato questo problema e non abbia sprecato più tempo su di esso. strano errore, è estremamente difficile da individuare quando si lavora con tratti. – EightBitBoy