2012-05-14 66 views
7

我正在測試一些使用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。

回答

5

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" 
} 

但是,請注意,您只能模擬出這樣的常規對象。如果你被困在一個Java庫中,你可以把Java對象的構造變成一個工廠方法並且模擬它。

8

我剛剛發現,我們總是可以通過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" 
}