我正在测试一些使用 java 库的时髦代码,我想模拟库调用,因为它们使用网络。 因此,要测试的代码如下所示:
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。
我刚刚发现我们总是可以通过 MetaClass 覆盖构造函数,因为 Grails 2 将在每次测试结束时重置 MetaClass 修改。
这一招比格鲁维的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"
}
MockFor
构造函数的第二个可选参数是 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"
}
但是请注意,您只能模拟像这样的时髦对象。 如果你坚持使用Java库,你可以将Java对象的构造拉到工厂方法中并模拟它。