2011-10-26 14 views
9

W Grails mam usługę, którą chcę przetestować w jednostce. Usługa wykorzystuje te Import:Grails/Groovy - używanie wielu @TestMixin

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

chcę usługę zrobić uzyskać dane i konwertować je do formatu JSON:

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

Sposób pomocnik pisałem budować JSON jest:

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

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

    return result.toString(); 
} 

W teście jednostkowym muszę dodać @TestMixin (ControllerUnitTestMixin), aby załadować adapter JSON. Ale muszę też dodać @TestMixin (DomainClassUnitTestMixin), aby móc sfałszować obiekt bazy danych.

Jakieś pomysły na to, jak mieć wiele @TestMixin lub czy jest to problem z projektowaniem, ponieważ mam import grails.web.JSONBuilder w klasie serwisowej? W przeciwnym razie muszę użyć biblioteki JAVA/JSON lub umieścić rzeczy JSON w kontrolerze.

To jest to, co chcę testy wyglądać:

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

} 

}

dostaję @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) klasy JsTreeJSONGeneratorServiceTests {

void testSomething() { 

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

    mockDomain(DataProfileStats, stats1); 

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

} 

}

dostaję @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) klasy JsTreeJSONGeneratorServiceTests {

void testSomething() { 

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

    mockDomain(DataProfileStats, stats1); 

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

} 

}

dostaję „Nie można określić duplikat adnotacji na tego samego członka: grails.test.mixin. TestMixin "wyjątek.

Dzięki

Odpowiedz

19

Znaleziono!

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

Gratulujemy rozwiązania. Jeśli jesteś w stanie, zaznacz swoją odpowiedź jako "zaakceptowaną", aby inni mogli uczyć się od ciebie sukcesu. Pozdrowienia ~ –

+0

Dziękuję - to mi pomogło (korzystałem z @Mock()). – duma

0

Podobno wynika to z Grails bug. Problem z mieszaniem w ControllerUnitTextMixin polega na tym, że on również (i/lub potencjalnie zrobi) wiele logiki niezwiązanych lub nieprzydatnych dla usług i jest w zasadzie rozwiązaniem raczej niż rozwiązaniem. Odpowiedź Scotta jest zdecydowanie skąpa i czysta w tym sensie, że nie wprowadzono żadnych innych zmian, ale biorąc pod uwagę pewien brak wstecznej kompatybilności z Grails 2.0, byłbym zainteresowany przyszłymi wersjami, które mogą, powiedzmy, wymuszać logikę w metodzie setUp() które mogą zostać złamane dla usług.

Więc pod względem kompletności, jestem w tym kolejną potencjalną obejście podjęte bezpośrednio z JIRA, cały kredyt do Ellery ruchome:

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

następnie

Wystarczy zaimportować util.converters.JSON zamiast Grails .converters.JSON i wszystko inne działa bezproblemowo.

Powiązane problemy