如何获取声明为 class 的 Geb 模块实例?
How to get a Geb module instance with its declared class?
在 Geb 版本 0.10 之前,下面的示例代码工作得很好:
package whatever
import geb.Module
import geb.Page
import geb.spock.GebSpec
class ExampleSpec extends GebSpec {
def 'MODULE - Y U NO HAVE THE RIGHT CLASS?'() {
when:
ExamplePage page = to ExamplePage
then:
verifySomething(page.theModule)
}
boolean verifySomething(ExampleModule module) {
// ...
}
}
class ExamplePage extends Page {
static content = {
theModule { module ExampleModule }
}
}
class ExampleModule extends Module {
}
我想升级到最新的 0.13.1,但显然已经引入了突破性的(我会说是倒退的)变化,结果是:
groovy.lang.MissingMethodException: No signature of method:
geb.navigator.NonEmptyNavigator.verifySomething() is applicable for
argument types: (geb.content.TemplateDerivedPageContent) values:
[whatever.ExamplePage -> theModule: whatever.ExampleModule]
我注意到从 0.11 版本开始也发生了同样的情况,但 class 不同,异常消息如下:
groovy.lang.MissingMethodException: No signature of method:
geb.navigator.NonEmptyNavigator.verifySomething() is applicable for
argument types: (geb.content.SimplePageContent) values: [theModule -
SimplePageContent (owner: whatever.ExamplePage, args: [], value:
null)]
为什么用给定的特定 class 声明的模块在运行时会丢失它?如何预防?
实现 Navigator
接口(包括从 Module
扩展的 类 )并从内容定义返回的对象被 TemplateDerivedPageContent
对象包裹,这些对象委托给底层对象但是还允许生成 meaningful path to the object for error reporting.
模块的包装在旧版本的 Geb 中工作,然后它被无意中删除,现在又回来了。尽管由于 TemplateDerivedPageContent
动态委托给基础对象,您仍然可以调用模块的所有方法,但在像您这样的情况下,您 运行 会遇到麻烦 - 当您想要强烈键入您的代码时使用模块。因此,我仍然不确定我们应该在这里牺牲什么 - 更好的错误报告或强类型的能力,并且这种包装可能会在 Geb 的未来版本中被删除。
幸运的是有一个解决方法 - 如果你想强类型代码使用模块然后使用 getter 而不是内容定义来声明它们。在你的情况下它将是:
class ExamplePage extends Page {
ExampleModule getTheModule() {
module ExampleModule
}
}
在 Geb 版本 0.10 之前,下面的示例代码工作得很好:
package whatever
import geb.Module
import geb.Page
import geb.spock.GebSpec
class ExampleSpec extends GebSpec {
def 'MODULE - Y U NO HAVE THE RIGHT CLASS?'() {
when:
ExamplePage page = to ExamplePage
then:
verifySomething(page.theModule)
}
boolean verifySomething(ExampleModule module) {
// ...
}
}
class ExamplePage extends Page {
static content = {
theModule { module ExampleModule }
}
}
class ExampleModule extends Module {
}
我想升级到最新的 0.13.1,但显然已经引入了突破性的(我会说是倒退的)变化,结果是:
groovy.lang.MissingMethodException: No signature of method: geb.navigator.NonEmptyNavigator.verifySomething() is applicable for argument types: (geb.content.TemplateDerivedPageContent) values: [whatever.ExamplePage -> theModule: whatever.ExampleModule]
我注意到从 0.11 版本开始也发生了同样的情况,但 class 不同,异常消息如下:
groovy.lang.MissingMethodException: No signature of method: geb.navigator.NonEmptyNavigator.verifySomething() is applicable for argument types: (geb.content.SimplePageContent) values: [theModule - SimplePageContent (owner: whatever.ExamplePage, args: [], value: null)]
为什么用给定的特定 class 声明的模块在运行时会丢失它?如何预防?
实现 Navigator
接口(包括从 Module
扩展的 类 )并从内容定义返回的对象被 TemplateDerivedPageContent
对象包裹,这些对象委托给底层对象但是还允许生成 meaningful path to the object for error reporting.
模块的包装在旧版本的 Geb 中工作,然后它被无意中删除,现在又回来了。尽管由于 TemplateDerivedPageContent
动态委托给基础对象,您仍然可以调用模块的所有方法,但在像您这样的情况下,您 运行 会遇到麻烦 - 当您想要强烈键入您的代码时使用模块。因此,我仍然不确定我们应该在这里牺牲什么 - 更好的错误报告或强类型的能力,并且这种包装可能会在 Geb 的未来版本中被删除。
幸运的是有一个解决方法 - 如果你想强类型代码使用模块然后使用 getter 而不是内容定义来声明它们。在你的情况下它将是:
class ExamplePage extends Page {
ExampleModule getTheModule() {
module ExampleModule
}
}