Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Michael_Keller
Active Contributor
Dear community, thanks to the blogs of bunysae and suketu.dave, I became interested in the test doubles topic again. Unfortunately, ABAP unit tests don't yet play the role in my day-to-day work as I would like - still, I'm sticking to the topic.

One important point in this context is the creation of test doubles (mocks) of database tables. So far I have had no idea how to do this. Because I had some time yesterday left, I worked with the Open SQL Test Double Framework. I've built a very simple example to see how it works in principle (no real world example, sorry). It's just an "one hour code hack", done on my SAP NetWeaver 7.52 Trial, that I want to share with you. Ok, let's get started 🙂

I wrote a small, global class to read client customizing from table T000.
CLASS zcl_system_clients DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.

PUBLIC SECTION.
TYPES clients TYPE TABLE OF t000 WITH KEY mandt.

METHODS get_client
IMPORTING
client TYPE mandt
RETURNING
VALUE(result) TYPE clients.
ENDCLASS.

CLASS zcl_system_clients IMPLEMENTATION.
METHOD get_client.
SELECT * FROM t000 AS clients
INTO TABLE result
WHERE mandt = client.
ENDMETHOD.
ENDCLASS.

That's the content of database table T000 in my SAP NetWeaver 7.52 Trial.


content of database table T000


Here is my local test class.
CLASS ltc_test DEFINITION FINAL
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

PUBLIC SECTION.
METHODS get_client_000 FOR TESTING.
METHODS get_client_001 FOR TESTING.
METHODS get_client_999 FOR TESTING.

PRIVATE SECTION.
ENDCLASS.

CLASS ltc_test IMPLEMENTATION.
METHOD get_client_000.
DATA(cut) = NEW zcl_system_clients( ).
DATA(result) = cut->get_client( '000' ).
cl_aunit_assert=>assert_not_initial( result ).
ENDMETHOD.

METHOD get_client_001.
DATA(cut) = NEW zcl_system_clients( ).
DATA(result) = cut->get_client( '001' ).
cl_aunit_assert=>assert_not_initial( result ).
ENDMETHOD.

METHOD get_client_999.
DATA(cut) = NEW zcl_system_clients( ).
DATA(result) = cut->get_client( '999' ).
cl_aunit_assert=>assert_not_initial( result ).
ENDMETHOD.
ENDCLASS.

This is the result when running the tests.


The tests for reading the customizing of clients 000 and 001 are ok. Client 999 doesn't exist, the test fails. That's fine - there is no client 999 in my system.

So either I have to create a client 999 in the database table T000 or I have to rethink my test. Another solution is to use a test double for the database table. Fortunately, this is possible with the class CL_OSQL_TEST_ENVIRONMENT ... and exactly what I want to try.

Here's the revision of my test class. Pay attention to the PRIVATE SECTION and the methods CLASS_SETUP and CLASS_TEARDOWN.
CLASS ltc_test DEFINITION FINAL
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

PUBLIC SECTION.
METHODS get_client_000 FOR TESTING.
METHODS get_client_001 FOR TESTING.
METHODS get_client_999 FOR TESTING.

PRIVATE SECTION.
CLASS-DATA osql_test_environment TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
ENDCLASS.


CLASS ltc_test IMPLEMENTATION.
METHOD class_setup.
osql_test_environment = cl_osql_test_environment=>create( VALUE #( ( 'T000' ) ) ).
DATA(clients_test_data) = VALUE zcl_system_clients=>clients( ( mandt = '000' mtext = 'Test double' )
( mandt = '001' mtext = 'Test double' )
( mandt = '999' mtext = 'Test double' ) ).
osql_test_environment->insert_test_data( clients_test_data ).
ENDMETHOD.

METHOD class_teardown.
osql_test_environment->destroy( ).
ENDMETHOD.

METHOD get_client_000.
DATA(cut) = NEW zcl_system_clients( ).
DATA(result) = cut->get_client( '000' ).
cl_aunit_assert=>assert_not_initial( result ).
ENDMETHOD.

METHOD get_client_001.
DATA(cut) = NEW zcl_system_clients( ).
DATA(result) = cut->get_client( '001' ).
cl_aunit_assert=>assert_not_initial( result ).
ENDMETHOD.

METHOD get_client_999.
DATA(cut) = NEW zcl_system_clients( ).
DATA(result) = cut->get_client( '999' ).
cl_aunit_assert=>assert_not_initial( result ).
ENDMETHOD.
ENDCLASS.

This is the result when rerunning the tests.


The test double seems to have worked. Unfortunately I couldn't find a way to easily and quickly trace whether the test double or the database table were accessed. Some hints from the experts?

Ok, that's all I have to say about my little research trip 🙂 Who is also interested in the topic: This blog and this page helped me.

 

Best regards, thanks for reading and please stay healthy

Michael

 


P.S.: Please support the virtual wishing well.

P.S.S.: Not tired of reading blogs? Check this blog by bfeeb8ed7fa64a7d95efc21f74a8c135.

16 Comments