2011-10-26 23 views
9

Trong Grails Tôi có một dịch vụ mà tôi muốn thử nghiệm đơn vị. Dịch vụ này sử dụng các hàng nhập khẩu:Grails/Groovy - sử dụng nhiều @TestMixin

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

Tôi muốn các dịch vụ làm có được dữ liệu và chuyển nó sang JSON:

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

Phương pháp helper tôi đã viết để xây dựng JSON là:

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

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

    return result.toString(); 
} 

Trong thử nghiệm đơn vị tôi phải thêm @TestMixin (ControllerUnitTestMixin) để bộ điều hợp JSON được nạp. Nhưng tôi cũng phải thêm @TestMixin (DomainClassUnitTestMixin) để tôi có thể giả lập đối tượng cơ sở dữ liệu.

Bất kỳ ý tưởng nào về cách có nhiều @TestMixin hoặc đây có phải là vấn đề thiết kế với tôi khi nhập grails.web.JSONBuilder trong lớp dịch vụ không? Nếu không, tôi phải sử dụng một thư viện JAVA/JSON hoặc đặt các công cụ JSON trong một bộ điều khiển.

Đây là những gì tôi muốn thử nghiệm để trông giống như:

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

} 

}

tôi nhận được một @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests lớp {

void testSomething() { 

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

    mockDomain(DataProfileStats, stats1); 

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

} 

}

tôi nhận được một @TestMixin (ControllerUnitTestMixin) @TestMixin (DomainClassUnitTestMixin) JsTreeJSONGeneratorServiceTests lớp {

void testSomething() { 

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

    mockDomain(DataProfileStats, stats1); 

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

} 

}

tôi nhận được một "Không thể chỉ định chú thích trùng lặp trên các thành viên cùng: grails.test.mixin. TestMixin "ngoại lệ.

Cảm ơn

Trả lời

19

Tìm thấy!

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

Chúc mừng giải pháp. Khi bạn có thể, hãy đảm bảo đánh dấu câu trả lời của bạn là 'được chấp nhận' để những người khác có thể học hỏi từ bạn thành công. Chúc mừng ~ –

+0

Cảm ơn bạn - điều này đã giúp tôi (tôi đã sử dụng @Mock()). – duma

0

Rõ ràng, điều này là do Grails bug. Vấn đề với sự pha trộn trong ControllerUnitTextMixin, là nó cũng làm (và/hoặc có khả năng sẽ làm) rất nhiều logic không liên quan hoặc không hữu ích cho các dịch vụ, và về cơ bản là một workaround chứ không phải là một sửa chữa. Câu trả lời của Scott chắc chắn là thưa thớt và sạch sẽ theo nghĩa là không có thay đổi nào khác, nhưng với một số thiếu khả năng tương thích ngược với Grails 2.0, tôi sẽ quan tâm đến các bản phát hành trong tương lai có thể, buộc logic vào phương thức setUp() có thể phá vỡ các dịch vụ.

Vì vậy, cho đầy đủ, tôi bao gồm một workaround tiềm năng lấy trực tiếp từ các JIRA, tất cả tín dụng cho 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)); 
    } 
} 

sau đó

Chỉ cần nhập util.converters.JSON thay vì grails .converters.JSON và mọi thứ khác hoạt động liên tục.