我在使用 Grails 2.0.1 进行重构时偶然发现了这一点,但我将这个问题的基础知识提取到了一个直接的 groovy 1.8.6 测试中,但它仍然失败了。我遇到它是因为我的方法过去不带参数,我将其更改为带 1 个参数。当我更改实施生产代码时,我的测试都没有失败。这很奇怪,因为我在测试中使用的 metaClassing 设置为不接受任何参数,但是当我传入参数时它仍然响应我的生产代码。因此,在下面的示例中,我想知道为什么要调用第二个 metaClassing 而不是第一个。它不接受任何参数,如您所见,我正在传递一个参数。如果您切换 metaClassing 的顺序,那么它可以正常工作,但顺序不应该 在这种情况下无关紧要,因为方法签名不同。任何有关为什么会发生这种情况的见解将不胜感激。
import groovy.util.GroovyTestCase
class FirstTest extends GroovyTestCase {
void testStuff() {
def object = new Object()
object.metaClass.someMethodName = {Object obj ->
"ONE"
}
object.metaClass.someMethodName = {
"TWO"
}
def result = object.someMethodName(new Object())
assert "ONE" == result //result is equal to "TWO" in this case
}
}
编辑
似乎我上面的代码可能比有用的更令人困惑,所以这里是实际的代码。
原始生产代码:
def create() {
render(view: "create", model: [domains: Domain.myCustomListMethod().sort{it.cn}])
}
原始测试代码:
@Test
void createShouldIncludeAListOfAllDomainsInModel() {
def directory = GldapoDirectory.newInstance(
"", [
url: "http://url.com",
userDn: "someUserName",
password: "superSecretPassword"
])
controller.session.userDirectory = directory
Domain.metaClass.'static'.myCustomListMethod = {
[[cn:"1"], [cn:"2"]]
}
controller.create()
assert [[cn:"1"], [cn:"2"]] == controller.modelAndView.model.domains
}
然后我更新了生产代码以传入,session.userDirectory
即使它没有设置为接收任何参数,我的测试仍然未经修改地通过:
def create() {
render(view: "create", model: [domains: Domain.list(session.userDirectory).sort{it.cn}])
}