2011-10-26 66 views
9

在Grails中我有一個服務,我想單元測試。該服務使用這些進口:Grails/Groovy - 使用多個@TestMixin

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

我想要的服務做獲取數據,並將其轉換成JSON:

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

的輔助方法,我寫信給構建JSON是:

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

} 

}

我得到一個@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 != ""; 

} 

}

我得到一個「不能指定同一部件上重複標註:grails.test.mixin。 TestMixin「異常。

謝謝

回答

19

找到了!

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

祝賀解決方案。如果可以,請確保將您的答案標記爲「已接受」,以便其他人可以向您學習成功。乾杯〜 –

+0

謝謝 - 這幫了我(我正在使用@Mock()雖然)。 – duma

0

顯然,這是由於Grails bug。在ControllerUnitTextMixin中混合的問題在於,它也會(和/或可能會做)很多與服務無關或無益的邏輯,並且本質上是一種解決方法而不是解決方法。斯科特的答案顯然是稀疏而乾淨的,因爲沒有其他改變,但考慮到一些缺乏向後兼容Grails 2.0的情況,我會關注將來的版本,比如強制邏輯進入setUp()方法這可能會因服務而中斷。

所以對於完整性,我包括直接從JIRA採取了另一個潛在的解決辦法,所有功勞都埃勒裏鶴:

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和其他一切無縫工作。