对于单元测试,我需要模拟Grails服务中使用的几个与Apache Thrift相关的Java类(THttpClient,TBinaryProtocol和一个生成的Client),但是使用常规的模拟技术时会遇到一些异常。我在服务中创建了 setter/getter (而不是在正在测试的方法中使用新的运算符)。解决的一个问题是Thrift类没有默认的构造函数,因此我创建了一个子类来满足模拟的要求:
class TestableTHttpClient extends THttpClient {
public TestableTHttpClient() {
super("http://example.com");
}
public TestableTHttpClient(String url) {
super(url);
}
}
我已经尝试过使用 mock mockFor()进行模拟,但是得到了 GroovyCastException :将映射转换为MyServiceTests $ TestableTHttpClient时出错,原因:null:
def mockTHttpClient = mockFor(TestableTHttpClient, true)
mockTHttpClient.demand.open { }
mockTHttpClient.demand.close { }
def mockTHttpClientInstance = mockTHttpClient.createMock() // fails
我已经尝试使用相同的GroovyCastException进行 map 强制:将 map 强制转换为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
我对元类进行了更改,该元类传递了两个类,但最后一个类(客户端)需要返回特定的模拟值。相反,真正的方法被调用: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书籍,除了域和 Controller 以外,几乎没有关于测试的内容。
最佳答案
尝试使用不同的模拟框架。我推荐Mockito。
关于unit-testing - 无法在Grails中模拟Thrift类进行测试(GroovyCastException),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21027874/