2011-10-26 10 views
9

En Grails tengo un servicio que quiero probar en una unidad. El servicio utiliza estas importaciones:Grails/Groovy: utilizando múltiples @TestMixin

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

Quiero que el servicio para hacer llegar los datos y convertirlo a JSON:

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

El método de ayuda que escribió para construir el JSON es:

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

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

    return result.toString(); 
} 

En la prueba de la unidad, tengo que agregar @TestMixin (ControllerUnitTestMixin) para que el adaptador JSON esté cargado. Pero también tengo que agregar @TestMixin (DomainClassUnitTestMixin) para poder simular el objeto de la base de datos.

¿Alguna idea sobre cómo tener múltiples @TestMixin o este es un problema de diseño cuando tengo una importación grails.web.JSONBuilder en una clase de servicio? De lo contrario, tengo que usar una biblioteca JAVA/JSON o poner las cosas JSON en un controlador.

Esto es lo que yo quiero la prueba para que parezca:

@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 != ""; 

} 

}

me siento un @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests clase {

void testSomething() { 

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

    mockDomain(DataProfileStats, stats1); 

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

} 

}

me siento un @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests clase {

void testSomething() { 

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

    mockDomain(DataProfileStats, stats1); 

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

} 

}

consigo un "No se puede especificar la anotación duplicado en el mismo miembro: grails.test.mixin. TestMixin "excepción.

Gracias

Respuesta

19

¡Lo encontró!

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

Felicidades por la solución. Cuando pueda, asegúrese de marcar su respuesta como 'aceptada' para que otros puedan aprender de su éxito. Saludos ~ –

+0

Gracias, esto me ayudó (aunque estaba usando @Mock()). – duma

0

Al parecer, esto se debe a un Grails bug. El problema con la mezcla en el ControllerUnitTextMixin, es que también hace (y/o potencialmente funcionará) una gran cantidad de lógica no relacionada o inútil para los servicios, y es esencialmente una solución en lugar de una solución. La respuesta de Scott es definitivamente escasa y limpia en el sentido de que no se realizan otros cambios, pero dada la falta de compatibilidad con Grails 2.0, me preocuparían las versiones futuras que podrían, por ejemplo, forzar la lógica en el método setUp() eso puede romperse por los servicios.

Así está completo, estoy incluyendo otra posible solución tomada directamente del JIRA, todo el crédito a Ellery Grúas:

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

continuación

Sólo tiene que importar util.converters.JSON en lugar de griales .converters.JSON, y todo lo demás funciona a la perfección.

Cuestiones relacionadas