Codebeispiele für die mindsquare Test Driven Development Schulung
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.
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.
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.
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.
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.
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.
Ermöglicht das Setzen des indirekten Inputs aus der Testklasse heraus.
Ablauf:
- Test setzt gewünschten Rückgabewert in Stub
- 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.
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.
Stellt eine einfache Implementierung der Dependent On Komponente dar.
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.
Ein Dummy erfüllt die syntaktischen Anforderungen ohne weitere Logik.
Übersicht über die verschiedenen Test Double Frameworks
Verfügbar ab:
- globale Interfaces: SAP NetWeaver 7.4 SP9
- globale Klassen: AS ABAP 7.53
- ABAP Test Double Framework – An Introduction
- Short examples of CL_ABAP_TESTDOUBLE
- Beispielcode auf GitHub
Verfügbar ab: AS ABAP 7.52
- Beispielcode:
SABP_UNIT_DOUBLE_OSQL_DEMO
- Dokumentation: ABAP SQL Test Double Framework
Verfügbar ab: AS ABAP 7.51
- Beispielcode:
SABP_UNIT_DOUBLE_CDS_DEMO
- Dokumentation: ABAP CDS Test Double Framework
Verfügbar ab: AS ABAP 7.56
- Beispielcode:
SABP_UNIT_DOUBLE_FUNCTION_DEMO
- Dokumentation: Managing Dependencies on ABAP Function Modules with ABAP Unit
Verfügbar ab: AS ABAP 7.55
- Beispielcode:
SABP_UNIT_AUTHORITY_DEMO
- Dokumentation: Managing Dependencies on ABAP Authority Checks with ABAP Unit
Verfügbar ab: SAP NetWeaver 7.5