2011-10-26 9 views
9

In Grails ho un servizio che voglio testare. Il servizio utilizza queste importazioni:Grails/Groovy - utilizzando più @TestMixin

import grails.converters.JSON 
import grails.web.JSONBuilder 

voglio il servizio per fare ottenere i dati e convertirlo in JSON:

def tables = DataProfileStats.withCriteria { 
     projections { 
      distinct("tableName")    
      } 
     }; 

Il metodo di supporto che ho scritto per costruire il JSON è:

public String buildNodeString(String nodeText) 
{ 
    def builder = new JSONBuilder(); 

    JSON result = builder.build { 
     hello = "world" 
     }; 

    return result.toString(); 
} 

Nel test dell'unità devo aggiungere @TestMixin (ControllerUnitTestMixin) in modo che l'adattatore JSON sia caricato. Ma devo anche aggiungere @TestMixin (DomainClassUnitTestMixin) in modo da poter prendere in giro l'oggetto del database.

Qualche idea su come avere più @TestMixin o si tratta di un problema di progettazione con me che ha un'importazione grails.web.JSONBuilder in una classe di servizio? Altrimenti, devo usare una libreria JAVA/JSON o mettere la roba JSON in un controller.

Questo è quello che voglio il test per assomigliare:

@TestMixin(ControllerUnitTestMixin) 
@TestMixin(DomainClassUnitTestMixin) 
class JsTreeJSONGeneratorServiceTests { 

void testSomething() { 

    DataProfileStats stats1 = new DataProfileStats(); 
    stats1.tableName = "table"; 

    mockDomain(DataProfileStats, stats1); 

    JsTreeJSONGeneratorService service = new JsTreeJSONGeneratorService(); 
    String json = service.buildNodeString(); 
    assert json != ""; 

} 

}

ottengo un @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests class {

void testSomething() { 

    DataProfileStats stats1 = new DataProfileStats(); 
    stats1.tableName = "table"; 

    mockDomain(DataProfileStats, stats1); 

    JsTreeJSONGeneratorService service = new JsTreeJSONGeneratorService(); 
    String json = service.buildNodeString(); 
    assert json != ""; 

} 

}

ottengo un @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests class {

void testSomething() { 

    DataProfileStats stats1 = new DataProfileStats(); 
    stats1.tableName = "table"; 

    mockDomain(DataProfileStats, stats1); 

    JsTreeJSONGeneratorService service = new JsTreeJSONGeneratorService(); 
    String json = service.buildNodeString(); 
    assert json != ""; 

} 

}

ottengo "Impossibile specificare l'annotazione duplicato sullo stesso membro: grails.test.mixin. TestMixin "eccezione.

Grazie

risposta

19

trovato!

@TestMixin([GrailsUnitTestMixin, ControllerUnitTestMixin, DomainClassUnitTestMixin]) 
+0

Congratulazioni per la soluzione. Quando sei in grado, assicurati di contrassegnare la tua risposta come "accettata" in modo che altri possano apprendere dal tuo successo. Saluti ~ –

+0

Grazie - questo mi ha aiutato (stavo usando @Mock() però). – duma

0

Apparentemente, questo è dovuto a un Grails bug. Il problema con il mix nello ControllerUnitTextMixin è che fa anche (e/o potenzialmente farà) molta logica non correlata o non utile ai servizi, ed è essenzialmente una soluzione alternativa piuttosto che una correzione. La risposta di Scott è decisamente scarsa e pulita nel senso che non vengono apportate altre modifiche, ma data la mancanza di retrocompatibilità con Grails 2.0, sarei interessato alle versioni future che potrebbero, per esempio, forzare la logica nel metodo setUp() che potrebbe rompersi per i servizi.

Così, per completezza, sto incluso un altro potenziale soluzione presa direttamente dalla JIRA, tutto il credito a Ellery Crane:

package util.converters 

import org.codehaus.groovy.grails.web.converters.configuration.ConvertersConfigurationHolder 
import org.codehaus.groovy.grails.web.converters.configuration.ConverterConfiguration 
import org.codehaus.groovy.grails.web.converters.configuration.DefaultConverterConfiguration 
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller 
import org.codehaus.groovy.grails.web.converters.Converter 
import org.codehaus.groovy.grails.web.converters.configuration.ChainedConverterConfiguration 

class JSON extends grails.converters.JSON{ 

    public JSON(Object target) { 
    super(target) 
    } 

    @Override 
    protected ConverterConfiguration<grails.converters.JSON> initConfig() {  
    ConverterConfiguration config = super.initConfig() 
    if(config.getOrderedObjectMarshallers().size() == 0){  
     initDefaultMarshallers() 
     config = super.initConfig() 
    } 
    return config 
    } 

    private void initDefaultMarshallers(){ 
    List<ObjectMarshaller<grails.converters.JSON>> marshallers = new ArrayList<ObjectMarshaller<grails.converters.JSON>>(); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.ArrayMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.ByteArrayMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.CollectionMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.MapMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.EnumMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.ProxyUnwrappingMarshaller<grails.converters.JSON>()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.DateMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.ToStringBeanMarshaller()); 

    boolean includeDomainVersion = true; 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.DomainClassMarshaller(includeDomainVersion)); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.GroovyBeanMarshaller()); 
    marshallers.add(new org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller()); 

    DefaultConverterConfiguration<grails.converters.JSON> cfg = new DefaultConverterConfiguration<grails.converters.JSON>(marshallers); 
    cfg.setEncoding("UTF-8"); 
    cfg.setCircularReferenceBehaviour(Converter.CircularReferenceBehaviour.DEFAULT) 
    cfg.setPrettyPrint(false); 
    ConvertersConfigurationHolder.setDefaultConfiguration(grails.converters.JSON.class, new ChainedConverterConfiguration<grails.converters.JSON>(cfg)); 
    } 
} 

poi

Basta importare util.converters.JSON invece di graal .converters.JSON, e tutto il resto funziona perfettamente.

Problemi correlati