2016-04-12 8 views
4

Bis zu Geb. Version 0.10 der Beispielcode unten hat gerade fein gearbeitet:Wie bekomme ich eine Geb-Modul-Instanz mit ihrer deklarierten Klasse?

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 { 

} 

I (regressive würde ich sagen) auf die neuesten 0.13.1 aber anscheinend der Bruch Änderung eingeführt wurde, welche Ergebnisse mit Upgrade wollte:

groovy.lang.MissingMethodException: Keine Signatur der Methode: geb.navigator.NonEmptyNavigator.verifySomething() ist für Argumenttypen: (geb.content.TemplateDerivedPageContent) Werte: [whatever.ExamplePage -> theModule: whatever.BeispielModul e]

ich bemerkt habe, dass das gleiche seit Version 0.11, aber mit unterschiedlicher Klasse geschieht, wird die Ausnahmemeldung wie folgt:

groovy.lang.MissingMethodException: Keine Unterschrift des Verfahrens: geb .navigator.NonEmptyNavigator.verifySomething() ist für Argumenttypen: (geb.content.SimplePageContent) Werte: [themodule - SimplePageContent (Inhaber: whatever.ExamplePage, args [], Wert: null)]

Warum deklariert Modul, das mit einer bestimmten Klasse deklariert wird, zur Laufzeit? Wie verhindere ich das?

Antwort

3

Objekte Umsetzung Navigator-Schnittstelle (die sich von Module verlauf enthält Klassen) und zurück von dem Inhalts Definitionen mit TemplateDerivedPageContent Objekte gewickelt sind, die Delegierten zu dem darunterliegenden Objekt, sondern auch ein meaningful path to the object for error reporting herzustellen ermöglichen.

Die Umhüllung von Modulen funktionierte in älteren Versionen von Geb, dann wurde es versehentlich entfernt und jetzt ist es wieder da. Obwohl Sie immer noch alle Methoden des Moduls aufrufen können, wenn es sich um TemplateDerivedPageContent handelt, das dynamisch an das zugrunde liegende Objekt delegiert wird, stoßen Sie in Fällen wie Ihnen auf Probleme - wenn Sie Ihren Code, der Module verwendet, stark eingeben möchten. Daher bin ich immer noch unentschlossen, was wir hier opfern sollten - bessere Fehlerberichterstattung oder die Fähigkeit, stark zu tippen, und diese Umhüllung könnte in einer zukünftigen Version von Geb entfernt werden.

Glücklicherweise gibt es eine Problemumgehung - wenn Sie stark Code eingeben möchten, der Module verbraucht, dann verwenden Sie einen Getter anstelle einer Inhaltsdefinition, um sie zu deklarieren. In Ihrem Fall wäre es:

class ExamplePage extends Page { 

    ExampleModule getTheModule() { 
     module ExampleModule 
    } 

} 
+0

Großartig, Rätsel gelöst. Ich war gerade dabei, in Geb Repo nach dem Break Commit zu suchen, um zu verstehen, was vor sich geht. Ich würde es eher so lösen, ohne starke Typen verwenden zu müssen, aber ich migriere die Codebase, die es bereits hat, und es macht die Migration viel größer, um das anzugehen. Wenn du dich interessierst, ist meiner Meinung nach der deklarierte Typ sowieso nicht großartig. Wäre es nicht möglich, die Instanz des deklarierten Typs mit dem Wrapper-Verhalten zu dekorieren, ohne den ursprünglichen Typ zu verbergen? – topr

+0

Das wäre ideal und wenn das machbar wäre, hätte ich es schon gemacht aber ich weiß nicht wie :). Wir werden hier Kompromisse eingehen müssen, die Frage ist, was der beste Kompromiss ist. – erdi

+0

Gibt es eine offene Diskussion über diese Angelegenheit, zu der ich beitragen könnte? – topr