Skip to content

mindsquare-Custom-Solutions/TDD_Samples

Repository files navigation

mindsquare Logo

Begleitmaterialien zur Test Driven Development (TDD) Schulung

Codebeispiele für die mindsquare Test Driven Development Schulung

Beispielcode

zcl_aunit_calculator

CLASS zcl_aunit_calculator DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS add
      IMPORTING number_1      TYPE i
                number_2      TYPE i
      RETURNING VALUE(result) TYPE i.
    METHODS divide
      IMPORTING number_1      TYPE i
                number_2      TYPE i
      RETURNING VALUE(result) TYPE i
      RAISING   cx_sy_zerodivide.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_aunit_calculator IMPLEMENTATION.
  METHOD add.
    result = number_1 + number_2.
  ENDMETHOD.

  METHOD divide.
    IF number_2 = 0.
      RAISE EXCEPTION TYPE cx_sy_zerodivide.
    ENDIF.

    result = number_1 / number_2.
  ENDMETHOD.
ENDCLASS.

zcl_aunit_converter

CLASS zcl_aunit_converter DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS: add_and_convert
      IMPORTING number_1      TYPE i
                number_2      TYPE i
                currency      TYPE waers
                bukrs         TYPE bukrs
      RETURNING VALUE(result) TYPE char20.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_aunit_converter IMPLEMENTATION.
  METHOD add_and_convert.
    data: sum_in_target_currency TYPE f.

    select single waers from t001 where bukrs = @bukrs into @data(target_currency).
    if sy-subrc <> 0.
        result = 'invalid bukrs'.
        return.
    endif.

    data(calculator) = new zcl_aunit_calculator(  ).

    data(sum) = calculator->add( number_1 = number_1 number_2 = number_2 ).

    call function 'CONVERT_TO_LOCAL_CURRENCY'
        EXPORTING
            date = sy-datum
            foreign_amount = sum
            foreign_currency = currency
            local_currency = target_currency
        IMPORTING
            local_amount = sum_in_target_currency
        EXCEPTIONS
            NO_RATE_FOUND = 1
            OVERFLOW = 2
            NO_FACTORS_FOUND = 3
            NO_SPREAD_FOUND = 4
            derived_2_times = 5
            OTHERS = 6.

    result = |{ sum_in_target_currency } { target_currency }|.
  ENDMETHOD.

ENDCLASS.

Injektionstechniken

Constructor Injection

Produktivcode

CLASS … DEFINITION … .
  PUBLIC SECTION.
    METHODS 
      constructor 
        IMPORTING 
          i_cash_provider TYPE REF TO if_cash_provider OPTIONAL.
  
  PRIVATE SECTION.
    DATA m_cash_provider TYPE REF TO if_cash_provider.
  …
ENDCLASS.

CLASS … IMPLEMENTATION.
  METHOD constructor.
    m_cash_provider = COND #( WHEN i_cash_provider IS BOUND
                                THEN i_cash_provider
                              ELSE NEW cl_cash_provider( ) ).
  ENDMETHOD.
  
  …
ENDCLASS.

Setter Injection

Produktivcode

CLASS … DEFINITION … .
  PUBLIC SECTION.
    METHODS 
      set_cash_provider 
        IMPORTING 
          i_cash_provider TYPE REF TO if_cash_provider.
  
  PRIVATE SECTION.
    DATA m_cash_provider TYPE REF TO if_cash_provider.
  …
ENDCLASS.

CLASS … IMPLEMENTATION.
  METHOD set_cash_provider.
    m_cash_provider = i_cash_provider.
  ENDMETHOD.
  …
ENDCLASS.

Parameter Injection

Produktivcode

CLASS … DEFINITION … .
  PUBLIC SECTION.
  METHODS 
    get_amount_in_coins
      IMPORTING
        i_amount TYPE i
        i_cash_provider TYPE REF TO if_cash_provider OPTIONAL
      RETURNING VALUE(r_value) TYPE i.

  PRIVATE SECTION.
    DATA m_cash_provider TYPE REF TO if_cash_provider.
  …
ENDCLASS.

CLASS … IMPLEMENTATION.
  METHOD get_amount_in_coins.
    DATA(cash_provider) = CAST if_cash_provider( COND #( 
      WHEN i_cash_provider IS BOUND
        THEN i_cash_provider
      ELSE NEW cl_cash_provider( ) ) ).
    …
  ENDMETHOD.
  …
ENDCLASS.

Backdoor Injection

Produktivcode

CLASS … DEFINITION … .
  PRIVATE SECTION.
    DATA m_cash_provider TYPE REF TO if_cash_provider.
  …
ENDCLASS

Testcode

CLASS ltc_get_amount_in_coins DEFINITION DEFERRED.
CLASS cl_money_machine DEFINITION LOCAL FRIENDS ltc_get_amount_in_coins.

CLASS ltc_get_amount_in_coins DEFINITION FOR TESTING … .
  …
ENDCLASS.

CLASS ltc_get_amount_in_coins IMPLEMENTATION.
  METHOD setup.
    "given
    m_cut = NEW #( ).
    m_cut->m_cash_provider = NEW ltd_cash_provider( ).
  ENDMETHOD.
ENDCLASS.

Test Double Terminologie

Stub

Ermöglicht das Setzen des indirekten Inputs aus der Testklasse heraus.

Ablauf:

  1. Test setzt gewünschten Rückgabewert in Stub
  2. Stub gibt den gewünschten Wert an den zu testenden Code
CLASS ltd_stub DEFINITION FOR TESTING.
  PUBLIC SECTION.
    INTERFACES if_cash_provider PARTIALLY IMPLEMENTED.
    
    DATA m_notes TYPE if_cash_provider=>tt_change.
ENDCLASS.

CLASS ltd_stub IMPLEMENTATION.
  METHOD if_cash_provider~get_notes.
    r_notes = m_notes.
  ENDMETHOD.
ENDCLASS.

Spy

Ermöglicht das Logging der vom Produktivcode an die Dependent On Komponente übergebenen Parameter.

Ablauf:

  • Spy protokolliert den vom Code under Test übergebenen Wert
  • Der Test verifiziert den aufgezeichneten Wert
CLASS ltd_spy DEFINITION FOR TESTING.
  PUBLIC SECTION.
    INTERFACES if_cash_provider PARTIALLY IMPLEMENTED.

    DATA m_currency TYPE string.
ENDCLASS.

CLASS ltd_spy IMPLEMENTATION.
  METHOD if_cash_provider~get_notes.
    m_currency = i_currency.
  ENDMETHOD.
ENDCLASS.

Fake

Stellt eine einfache Implementierung der Dependent On Komponente dar.

Mock

Erweiterung der Konzepte Stub, Spy und Fake. Verifiziert je nach Anforderung den indirekten Output und/oder stellt indirekten Input zu Verfügung.

Ablauf:

  • Test setzt gewünschten Wert im Mock
  • Spy protokolliert den vom Code under Test übergebenen Wert
  • Stub gibt den gewünschten Wert an den Code under Test zurück
  • Der Test verifiziert den aufgezeichneten Wert
CLASS ltd_mock DEFINITION FOR TESTING.
  PUBLIC SECTION.
    INTERFACES if_cash_provider PARTIALLY IMPLEMENTED.
  
    DATA m_currency TYPE string.
    DATA m_currency_exp TYPE string.
    DATA m_notes TYPE if_cash_provider=>tt_change.
ENDCLASS.

CLASS ltd_mock IMPLEMENTATION.
  METHOD if_cash_provider~get_notes.
    m_currency = i_currency.
    r_notes = m_notes.
  ENDMETHOD.

  METHOD assert_expectations.
    cl_abap_unit_assert=>assert_equals( act = m_currency
                                        exp = m_currency_exp ).
  ENDMETHOD.
ENDCLASS.

Dummy

Ein Dummy erfüllt die syntaktischen Anforderungen ohne weitere Logik.

Test Double Frameworks

Übersicht über die verschiedenen Test Double Frameworks

ABAP OO Test Double Framework

Verfügbar ab:

  • globale Interfaces: SAP NetWeaver 7.4 SP9
  • globale Klassen: AS ABAP 7.53

ABAP SQL Test Double Framework

Verfügbar ab: AS ABAP 7.52

ABAP CDS Test Double Framework

Verfügbar ab: AS ABAP 7.51

ABAP Function Module Test Double Framework

Verfügbar ab: AS ABAP 7.56

ABAP Authority Check Test Helper API

Verfügbar ab: AS ABAP 7.55

Test Seams

Verfügbar ab: SAP NetWeaver 7.5

About

Test Driven Development Examples

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages