gpt4 book ai didi

java - 元类构造函数覆盖不适用于@CompileStatic 注释类内部的方法

转载 作者:行者123 更新时间:2023-11-29 04:05:08 38 4
gpt4 key购买 nike

当我们对任何特定类(如 RESTClient)使用 someClass.metaClass.constructor 时,在用 @CompileStatic 注释的类的方法中可用,构造函数覆盖根本不起作用。

当我们删除 @CompileStatic 注释时,它可以正常工作。我错过了什么吗?

示例代码:

@CompileStatic
class FooClass {

String getDataFromProvider() {
String url = "https://www.example.com"
RESTClient restClient = new RESTClient(url)

HttpResponseDecorator response = restClient.post([:]) as HttpResponseDecorator
return response
}
}

和测试用例:

import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.RESTClient
import spock.lang.Specification

class FooContentSpec extends Specification {

void "test getDataFromProvider method"() {
given: "Rest url"
String restURL = "https://www.example.com"

and: "Mock RESTClient"
RESTClient mockedRestClient = Mock(RESTClient)

// THIS IS NOT WORKING
RESTClient.metaClass.constructor = { Object url ->
assert restURL == url
return mockedRestClient
}

mockedRestClient.metaClass.post = { Map<String, ?> args ->
return ""
}

when: "We hit the method"
HttpResponseDecorator response = Content.getDataFromProvider()

then: "We should get status 200"
response.statusCode == 200
}
}

根据Groovy Lang文档:

MockFor and StubFor can not be used to test statically compiled classes e.g for Java classes or Groovy classes that make use of @CompileStatic. To stub and/or mock these classes you can use Spock or one of the Java mocking libraries.

预期行为

在这种情况下,RESTClient 的构造函数覆盖应该在我们的测试用例中起作用,因为我们不想在每个测试用例中都使用第三方 API。

实际行为

不幸的是,RESTClient 不会因为 @CompileStatic 注释而被模拟,它每次都会命中 API。

环境信息

------------------------------------------------------------
Gradle 3.5
------------------------------------------------------------

Groovy: 2.4.10,
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015,
JVM: 1.8.0_221 (Oracle Corporation 25.221-b11),
OS: Mac OS X 10.15.2 x86_64

吉拉:https://issues.apache.org/jira/browse/GROOVY-9353

最佳答案

你是对的 @CompileStatic 不能与元类操作结合使用。原因是,顾名思义,所有内容都在编译时解析和绑定(bind),因此没有元类查找,因此无法覆盖它。

我建议研究 IoC/依赖项注入(inject),这样您就可以将模拟注入(inject)到您的代码中。使用经典单例会使您的代码更难测试。

关于java - 元类构造函数覆盖不适用于@CompileStatic 注释类内部的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59476058/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com