我正在测试一些使用java库的groovy代码,我想模拟库调用,因为他们使用网络。因此,测试中的代码类似于:
def verifyInformation(String information) {
def request = new OusideLibraryRequest().compose(information)
new OutsideLibraryClient().verify(request)
}
我尝试使用MockFor和StubFor,但我收到错误,例如:
No signature of method: com.myproject.OutsideLibraryTests.MockFor() is applicable for argument types: (java.lang.Class) values: [class com.otherCompany.OusideLibraryRequest]
我正在使用Grails 2.0.3。
答案 0 :(得分:9)
我刚刚发现我们总是可以通过MetaClass覆盖构造函数,因为Grails 2将在每次测试结束时重置MetaClass修改。
这个技巧比Groovy的MockFor
更好。例如,AFAIK,Groovy的MockFor
不允许我们模拟JDK的类java.io.File
。但是,在下面的示例中,您不能使用File file = new File("aaa")
,因为实际对象类型是Map
,而不是File
。这个例子是Spock规范。
def "test mock"() {
setup:
def fileControl = mockFor(File)
File.metaClass.constructor = { String name -> [name: name] }
def file = new File("aaaa")
expect:
file.name == "aaaa"
}
答案 1 :(得分:6)
MockFor
's constructor的第二个可选参数是interceptConstruction
。如果将此属性设置为true,则可以模拟构造函数。例如:
import groovy.mock.interceptor.MockFor
class SomeClass {
def prop
SomeClass() {
prop = "real"
}
}
def mock = new MockFor(SomeClass, true)
mock.demand.with {
SomeClass() { new Expando([prop: "fake"]) }
}
mock.use {
def mockedSomeClass = new SomeClass()
assert mockedSomeClass.prop == "fake"
}
但是,请注意,您只能模拟像这样的groovy对象。如果您遇到Java库,可以将Java对象的构造转换为工厂方法并模拟它。