Grails / Groovy - использование нескольких @TestMixin - PullRequest
9 голосов
/ 26 октября 2011

В Grails у меня есть сервис, который я хочу пройти модульное тестирование.Служба использует следующие операции импорта:

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

Я хочу, чтобы служба получала данные и преобразовывала их в JSON:

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

Вспомогательный метод, который я написал для построения JSON:1007 *

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

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

    return result.toString();
}

В модульном тесте я должен добавить @TestMixin (ControllerUnitTestMixin), чтобы загрузить адаптер JSON.Но я также должен добавить @TestMixin (DomainClassUnitTestMixin), чтобы я мог издеваться над объектом базы данных.

Любые идеи о том, как использовать несколько @TestMixin, или это проблема дизайна, когда у меня есть импорт grails.web.JSONBuilderв классе обслуживания?В противном случае мне придется использовать библиотеку JAVA / JSON или поместить JSON-содержимое в контроллер.

Вот как я хочу, чтобы тест выглядел следующим образом:

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

}

}

Я получаю класс @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests {

void testSomething() {

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

    mockDomain(DataProfileStats, stats1);

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

}

} ​​

Я получаю класс @TestMixTinTixTinSiteTixTinSiteTecitSit (@TestMixinTextMixTinSigner){

void testSomething() {

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

    mockDomain(DataProfileStats, stats1);

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

}

}

Я получаю исключение «Невозможно указать дубликат аннотации для одного и того же члена: grails.test.mixin.TestMixin».

Спасибо

Ответы [ 2 ]

20 голосов
/ 28 октября 2011

Нашли!

@TestMixin([GrailsUnitTestMixin, ControllerUnitTestMixin, DomainClassUnitTestMixin])
0 голосов
/ 15 ноября 2013

Очевидно, это связано с ошибкой Grails . Проблема с микшированием в ControllerUnitTextMixin заключается в том, что он также делает (и / или потенциально может сделать) большую логику, не связанную или бесполезную для сервисов, и по сути является обходным, а не исправлением. Ответ Скотта определенно скуден и ясен в том смысле, что никаких других изменений не сделано, но, учитывая некоторую нехватку обратной совместимости с Grails 2.0, я буду обеспокоен будущими выпусками, которые, скажем, могут заставить логику внедрять метод setUp () это может сломаться для услуг.

Итак, для полноты, я включаю еще один потенциальный обходной путь, взятый непосредственно из JIRA , все заслуги перед 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));
  }
}

тогда

Просто импортируйте util.converters.JSON вместо grails.converters.JSON, и все остальное работает без проблем.

...