无法在Grails中模拟Thrift类进行测试(GroovyCastException)

时间:2014-01-09 18:07:37

标签: unit-testing grails groovy mocking thrift

对于单元测试,我需要模拟在Grails服务中使用的几个与Apache Thrift相关的Java类(THttpClient,TBinaryProtocol和生成的客户端),但在使用通常的模拟技术时遇到了几个例外。我在服务中创建了getter(而不是在我测试的方法中使用新的运算符)。解决的一个问题是Thrift类没有默认构造函数,所以我创建了一个子类来满足模拟的要求:

class TestableTHttpClient extends THttpClient {
     public TestableTHttpClient() {
         super("http://example.com");
     }
     public TestableTHttpClient(String url) {
         super(url);
     }
}

我尝试使用mockFor()进行模拟,但得到 GroovyCastException :错误地将地图投射到MyServiceTests $ TestableTHttpClient,原因:null:

def mockTHttpClient = mockFor(TestableTHttpClient, true)
mockTHttpClient.demand.open { }
mockTHttpClient.demand.close { }
def mockTHttpClientInstance = mockTHttpClient.createMock() // fails

我尝试使用相同的GroovyCastException进行地图强制:将地图投射到MyServiceTests时出错错误$ TestableTHttpClient

def mockTHttpClientInstance = [
    open: { },
    close: { }
] as TestableTHttpClient]

我尝试过使用与上述相同的例外情况。

def helperMethod = { assert 1 == 1 }
def helper = [open:helperMethod, close:helperMethod]
def mockTHttpClientInstance = helper as TestableTHttpClient // fails

我对元类进行了更改,它传递了两个类,但最后一个类(Client)我需要返回一个特定的模拟值。相反,真正的方法被调用:TTransportException:没有更多的数据可用。

def mockTHttpClientInstance = new TestableTHttpClient()
mockTHttpClientInstance.metaClass.invokeMethod = { String name, args -> }
def mockTBinaryProtocolInstance = new TestableTBinaryProtocol()
mockTBinaryProtocolInstance.metaClass.invokeMethod = { String name, args -> }   
def mockClientInstance = new TestableClient()
// mockClientInstance.metaClass.invokeMethod = { String name, args -> }
mockClientInstance.metaClass.methodINeedToMockResults = { String name -> true }

def mockMyService = [
    getTHttpClient: { String -> mockTHttpClientInstance },
    getTBinaryProtocol: { TTransport -> mockTBinaryProtocolInstance },
    getClient: { TProtocol -> mockClientInstance }
] as MyService

有什么建议吗?我已经阅读了http://grails.org/doc/latest/guide/testing.html并且我知道的Grails书籍除了域名和控制器之外几乎没有其他测试。

1 个答案:

答案 0 :(得分:0)

尝试使用不同的模拟框架。我推荐Mockito