Introduction
AMDP classes wrap database procedures written in SQLScript or Native SQL.
The table entities used in Open SQL statments can be replaced by test-doubles with the Open SQL replacement service. Table entities used in SQLScript or Native SQL statements can't be replaced with this service. If the AMDP class doesn't implement a CDS table function, we can't use the CDS Test Double Framework. So a suitable solution is the ABAP Test Double Framework.
AMDP classes
AMDP classes are in principle normal ABAP classes with a few particularities:
- They were thought for database procedures, which can't be easily implemented in Open SQL or in ABAP-CDS
- They must implement a database specific tag interface (
IF_AMDP_MARKER_+ suffix for database system):
IF_AMDP_MARKER_HDBfor HANA databases
This concept can be expanded to other database systems, but HANA is the only supported database for now. - They contain AMDP methods, which implement the database procedures
AMDP methods
AMDP methods require a specific parameter interface:
- only elementary data types or tables types with a elementary row type are supported
- parameters must be passed by value
- no return parameters can be declared
- the implementation can't be empty
A sample AMDP class can be seen below.
INTERFACE zif_flight_accessor
PUBLIC .
METHODS increase_price
IMPORTING
VALUE(clnt) TYPE sy-mandt
VALUE(carrid) TYPE s_carr_id
VALUE(connid) TYPE s_conn_id
VALUE(fldate) TYPE s_date
VALUE(increment) TYPE sflight-price.
ENDINTERFACE.
CLASS zflight_accessor DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_flight_accessor .
INTERFACES if_amdp_marker_hdb.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zflight_accessor IMPLEMENTATION.
METHOD zif_flight_accessor~increase_price
BY DATABASE PROCEDURE FOR HDB
LANGUAGE SQLSCRIPT
USING sflight.
update sflight set price = price + :increment
where mandt = :clnt and carrid = :carrid
and connid = :connid and fldate = :fldate;
ENDMETHOD.
ENDCLASS.
AMDP methods can be called like any other method. For this reason, the AMDP method
INCREASE_PRICE in class ZFLIGHT_ACCESSOR is packed behind an interface. When an AMDP method can be called like any other method, it's possible to create a test-double with the ABAP Test Double Framework.A simple test-double for
INCREASE_PRICE is created like this:
increase_price_test_double ?= cl_abap_testdouble=>create( object_name = 'ZIF_FLIGHT_ACCESSOR' ).
cl_abap_testdouble=>configure_call( increase_price_test_double )->and_expect( )->is_called_once( ).
increase_price_test_double->increase_price( clnt = sy-mandt increment = 10
carrid = 'TG' connid = 924 fldate = '20200420' ).
This creates a mock with the expectation
INCREASE_PRICE is called once with the parameters:
increment = 10carrid = 'TG'connid = 924fldate = '20200420'
.
The expectation can be verified with the statement
cl_abap_testdouble=>verify_expectations( increase_price_test_double ).Conclusion
Instead of replacing a table entity with the OpenSQL replacement service, we can replace the AMDP class by an test-double. This approach doesn't cover the SQL statements, but it can be helpful for creating deterministic unit tests.