【问题标题】:How to mock the 'new' operator如何模拟“新”运算符
【发布时间】:2012-05-14 18:52:06
【问题描述】:

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

【问题讨论】:

    标签: testing grails groovy constructor mocking


    【解决方案1】:

    我刚刚发现我们总是可以通过 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"
    }
    

    【讨论】:

    • 您可能希望在您的测试(或课程)之前使用@ConfineMetaClassChanges([File]),它可以隔离您对FilemetaClass 所做的更改;见spockframework.org/spock/docs/1.1/…
    【解决方案2】:

    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 对象的构造拉入工厂方法并模拟它。

    【讨论】:

    • 我无法在网络上找到一个示例,其类只有带参数的构造函数。你知道上面的例子在这种情况下会是什么样子吗?
    • 我正在尝试模拟metricsHandler = new DeploymentMetrics(steps, env, docker) metricsHandler.postMetric(team, service)
    • 如果我尝试:def stub = new StubFor(DeploymentMetrics, true) stub.demand.with { DeploymentMetrics() {steps,env,docker -> new Expando(steps:steps, env:env, docker:docker)} postMetric() {a,b,c,d,e,f,g -> "from mock with proxy"} } 我得到了Cannot cast object '{steps=some, env={getEnvironment=vars.Testingq$_setUp_closure1@7cd65eb1}, docker=com.lesfurets.jenkins.unit.DockerMock@54dfe857}' with class 'groovy.util.Expando' to class 'spg.dora.cd.DeploymentMetrics'
    猜你喜欢
    • 1970-01-01
    • 2021-09-18
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 2022-01-12
    • 2011-04-10
    • 2021-01-08
    相关资源
    最近更新 更多