This is a test message to test the length of the message box.
Login
|
ABAP OO Injector
Erstellt von Software-Heroes

ABAP OO - Injector

217

Beim letzten Artikel hatten wir uns ABAP OO und die Evolution der Design Pattern angeschaut und wie wir sie am besten nutzen können. Daher gehen wir in diesem Artikel noch einmal in die Details des Injector für die Testbarkeit.

Werbung


In diesem Artikel schauen wir uns die Funktionsweise des Injectors und wie du diesen zusammen mit der Factory verwenden kannst, um einfache Testbarkeit zu ermöglichen.

 

Einleitung

Im letzten Blog der Serie hatten wir uns die Factory und den Singleton einmal im Detail angeschaut. Dort haben wir uns die verschiedenen Stufen der Evolution angeschaut und wie wir das Pattern weiter ausbauen können. Diesen Artikel solltest du als Grundlage lesen, bevor du mit diesem Artikel weiter machst. Dabei wollen wir nun die Factory nutzen und diese für unsere Unit Tests vorbereiten, ohne das eigentliche Coding in der Implementierung ändern zu müssen.

 

Herausforderung

Aktuell haben wir eine globale Klasse im System, die einen Zeitstempel validieren soll. Die Klasse erzeugt über die Factory eine Instanz unserer Implementierung und gibt sie in die Methode. Dort prüfen wir gegen einen spezifischen Zeitstempel in der Zukunft. Schaust du dir das Coding an, dann müssten wir aber warten, bis der Unit Test einmal funktioniert.

CLASS zcl_bs_demo_oo_test DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS validate_timestamp
      RETURNING VALUE(result) TYPE abap_boolean.
ENDCLASS.


CLASS zcl_bs_demo_oo_test IMPLEMENTATION.
  METHOD validate_timestamp.
    DATA(timestamp) = zcl_bs_demo_oo_factory=>create( ).
    RETURN xsdbool( timestamp->get_timestamp( ) = '20991231063000.0000000' ).
  ENDMETHOD.
ENDCLASS.

 

Im Moment haben wir also unsere Komponente mit einem Unit Test. Zur Laufzeit ruft der Unit Test die Methode auf, die dann über die Factory eine Instanz zurückbekommt. Allerdings wird unser Unit Test erst in viele Jahren funktionieren und dann nur für einen sehr kleinen Bruchteil. Damit ist die Komponente erst einmal nicht gut testbar.

 

Erweiterung

Dazu erweitern wir das Szenario der Factory und der bisherigen Objekte um eine weitere Dimension. In diesem Kapitel schauen wir uns die verschiedenen Bestandteile an und erweitern sie.

 

Grundlage

Aus dem letzten Artikel benötigen wir die folgenden Objekte, wobei wir für unseren Fall nur die Factory verändern werden:

  • ZCL_BS_DEMO_OO_FACTORY
  • ZCL_BS_DEMO_OO_PRIVATE
  • ZIF_BS_DEMO_OO_INTERFACE

 

Injector

Wir müssen nun zwei Anpassungen gleichzeitig durchführen, dazu legen wir uns im ersten Schritt den neuen Injector ZCL_BS_DEMO_OO_INJECTOR als globale Klasse an.

CLASS zcl_bs_demo_oo_injector DEFINITION
  PUBLIC ABSTRACT FINAL
  CREATE PUBLIC
  FOR TESTING.

  PUBLIC SECTION.
    CLASS-METHODS inject_double
      IMPORTING double TYPE REF TO zif_bs_demo_oo_interface OPTIONAL.
ENDCLASS.


CLASS zcl_bs_demo_oo_injector IMPLEMENTATION.
  METHOD inject_double.
    zcl_bs_demo_oo_factory=>double = double.
  ENDMETHOD.
ENDCLASS.

 

Der Injector hat mehrere Eigenschaften, die für die Verwendung und Nutzung wichtig sind:

  • ABSTRACT - Die Klasse soll nicht instanziierbar sein, sondern nur über die bereitgestellten Methoden und Attribute funktionieren.
  • FOR TESTING - Die Klasse soll nur im Falle eines Unit Tests verwendbar sein. Grundsätzlich wird in Test- und Produktivsystemen der Code nicht kompiliert, das aber als zusätzliches Sicherheitsnetz.
  • OPTIONAL - Der Double ist statisch und sollte für weitere Unit Tests auch löschbar sein. Daher setzen wir den Parameter auf Optional.

 

Factory

Im nächsten Schritt passen wir unsere Factory an. Als ersten Schritt definieren wir den Injector als GLOBAL FRIEND, damit dieser auch auf geschützte Methoden und Attribute zugreifen kann. Als Zweites definieren wir ein statisches Attribut, dass zur Laufzeit den DOUBLE enthält und als letzten Schritt sorgen wir dafür, dass die CREATE Methode uns den Double gibt, wenn dieser gesetzt wurde.

CLASS zcl_bs_demo_oo_factory DEFINITION
  PUBLIC ABSTRACT FINAL
  GLOBAL FRIENDS zcl_bs_demo_oo_injector.

  PUBLIC SECTION.
    CLASS-METHODS create
      RETURNING VALUE(result) TYPE REF TO zif_bs_demo_oo_interface.

  PRIVATE SECTION.
    CLASS-DATA double TYPE REF TO zif_bs_demo_oo_interface.
ENDCLASS.


CLASS zcl_bs_demo_oo_factory IMPLEMENTATION.
  METHOD create.
    IF double IS INITIAL.
      RETURN NEW zcl_bs_demo_oo_private( ).
    ELSE.
      RETURN double.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

Zum Abschluss nicht vergessen beide Objekte (Injector und Factory) zu aktivieren.

 

Test

Wir haben nun alles vorbereitet für unseren Test. Schauen wir uns nun das aktuelle Szenario an und zwei Varianten, wie wir den Injector sinnvoll nutzen können.

 

Funktion

Unser Injector ist nun vorbereitet, damit wir über diesen ein Test Double in die Factory bringen können, welches wir dann im Unit Test verwenden. Damit testen wir nur noch das Verhalten unserer Methode VALIDATE_TIMESTAMP und nicht mehr die Abhängigkeit zur Implementierung in der Timestamp Klasse.

 

Lokale Klasse

Als erste Variante definieren wir uns eine lokale Hilfsklasse, wo wir das Interface implementieren. Da wir die Klasse als FOR TESTING gekennzeichnet haben, können wir PARTIALLY IMPLEMENTED verwenden und müssen nicht alle Methoden aus dem Interface implementieren.

CLASS lhc_double DEFINITION FOR TESTING.
  PUBLIC SECTION.
    INTERFACES zif_bs_demo_oo_interface PARTIALLY IMPLEMENTED.
ENDCLASS.


CLASS lhc_double IMPLEMENTATION.
  METHOD zif_bs_demo_oo_interface~get_timestamp.
    RETURN '20991231063000.0000000'.
  ENDMETHOD.
ENDCLASS.

 

Bevor wir dann unseren Testcode ausführen, verwenden wir den Injector, erzeugen eine neue Instanz unserer Hilfsklasse und übergeben die Instanz. Der Injector setzt dann den DOUBLE in der Factory, welcher für den Unit Test verwendet wird.

zcl_bs_demo_oo_injector=>inject_double( NEW lhc_double( ) ).

 

Test Double Framework

Als zweite Variante können wir das Test Double Framework verwenden. Dabei brauchen wir die lokale Implementierung mit dem Interface nicht, müssen aber einige Schritte ausführen, um den Double vorzubereiten. Weitere Informationen zum Framework bekommst du in diesem Artikel.

DATA(double) = CAST zif_bs_demo_oo_interface( cl_abap_testdouble=>create( 'zif_bs_demo_oo_interface' ) ).
cl_abap_testdouble=>configure_call( double )->ignore_all_parameters( )->returning( '20991231063000.0000000' ).
double->get_timestamp( ).

 

Als letzten Schritt übergeben wir den erstellten und vorbereiteten Double an den Injector und führen wieder unseren Test aus.

zcl_bs_demo_oo_injector=>inject_double( double ).

 

Ergebnis

Beide Unit Tests sind nun lauffähig und wir erreichen den Timestamp doch eher und öfters, um unsere Unit Tests auf Grün zu bekommen.

 

Komplettes Beispiel

Den kompletten Quellcode der Beispiele findest du im entsprechenden GitHub Repository von uns. Das meiste Coding wirst du in diesem Artikel finden, vor allem bei der Ausführung und Verwendung haben wir aber nur die wichtigsten Teile gezeigt.

 

Fazit

In diesem Artikel wollten wir den Injector näherbringen und wie du ihn in zukünftigen Projekten einfach und effektiv nutzen kannst, um deinen Code testbar zu bauen und für andere Entwickler zur Verfügung zu stellen.


Enthaltene Themen:
OOABAP OOInjector
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Dienstag und Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


ADT - RAP Analyzer [MIA]

Kategorie - ABAP

Die Einarbeitung und Übersicht in bestehende RAP Objekte kann nicht immer einfach sein, vor allem wenn es sich um komplexe Objekte handelt. Fragen wie das verwendete Pattern und wichtige Objekte müssen sich meist erarbeitet werden.

24.02.2026

ADT - Metadata Wizard [MIA]

Kategorie - ABAP

In diesem Artikel schauen wir uns den Metadata Wizard an und wie er vielleicht in Zukunft dein Leben bei der Anlage von UI-Annotationen in RAP vereinfachen könnte.

16.01.2026

030: Software-Heroes - My Community

Kategorie - YouTube

Du möchtest das neuste ABAP und SAP Wissen haben und auch nicht jeden Blog einzeln absuchen? My Community bringt den gesamten Community Content in eine Mini-App, die du nach deinen Vorstellungen anpassen kannst, um so keine Neuigkeiten mehr zu verpassen.

22.12.2025

ABAP Tools - IDE Actions (Tabelle)

Kategorie - ABAP

Wie kannst du eigentlich eine Tabelle erzeugen und in der IDE Action bearbeiten? Schauen wir uns die Möglichkeiten für die Eingabe an und wie du am Ende mit den Daten umgehen kannst.

09.12.2025

ABAP Tools - IDE Actions (Seiteneffekt)

Kategorie - ABAP

Wie können wir eigentlich automatisch Informationen auf dem UI aktualisieren, wenn etwas mit der IDE Action passiert? Schauen wir uns einmal die Side Effects im Detail an.

18.11.2025