
SAP has been doing some really good work upgrading its tools. We have recently upgraded to SAP_ABAP 740. I'm an advocate of ABAP Unit testing and this upgrade gave me the opportunity to try an example on the new Test Double Framework. Prajul Meyana's ABAP Test Double Framework - An Introduction says that the new framework is available from SP9. We're in SP8, but I can't wait to tesdrive this. So I started poking around. One of my colleagues pointed out that CL_ABAP_TESTDOUBLE is delivered with the release. YEY!
Below is an example of behavior verification using the framework and it appears to work. Maybe later, I'll make a much simpler cut. At this stage I just wanted to run it through a real life example within our code base.
Below is my application code. It's a simple custom service implementation to create Chart of Authority records for Opentext Vendor Invoice Management. ( It's not relevant here but note that we use FEH to manage exceptions for enterprise service errors. Maybe I can show a test of that exception in a later blog. )
Further below is one of my test classes with one of the test methods implemented.
The test double framework does three important things in this example .
I use a factory implementation to inject test doubles. Some of you don't like it. I understand that. Hope that doesn't distract from the intent. Have fun. As I mentioned when my colleague Custodio de Oliveira pointed it out that it's available, "Let's break it".
App Code |
---|
METHOD ZIF_FEH~PROCESS. DATA: lo_coa_user TYPE REF TO zif_opentext_vim_coa_user, lo_cx_opentext TYPE REF TO zcx_opentext_service, lo_cx_coa_user TYPE REF TO zcx_opentext_service, ls_main_error TYPE bapiret2, lt_coa_details TYPE zopentext_coa_details_tt, ls_coa_details TYPE LINE OF zopentext_coa_details_tt, lv_manager_id TYPE /ors/umoid, lv_max_counter TYPE /opt/counter. FIELD-SYMBOLS: <ls_process_coa_details> TYPE LINE OF zopentext_coa_detl_process_tt. me->_s_process_data = is_process_data. TRY. TRY. lo_coa_user = zcl_vim_coa_user_factory=>get_instance( )->get_coa_user( iv_windows_id = _s_process_data-windows_id iv_active_users_only = abap_false ). lv_manager_id = lo_coa_user->get_manager_id( ). CATCH zcx_opentext_service INTO lo_cx_coa_user. CLEAR lv_manager_id. ENDTRY. LOOP AT _s_process_data-coa_details[] ASSIGNING <ls_process_coa_details> WHERE start_date <= sy-datum AND end_date >= sy-datum. " Record removed in ECC if not in validity date ADD 1 TO lv_max_counter. ls_coa_details-counter = lv_max_counter. ls_coa_details-expense_type = <ls_process_coa_details>-expense_type. ls_coa_details-approval_limit = <ls_process_coa_details>-approval_limit. ls_coa_details-currency = <ls_process_coa_details>-currency. ls_coa_details-bukrs = '*'. " Functional requirement in ECC to set CoCode to *. Assumption : From corp - 1 user = 1 co code ls_coa_details-kostl = '*'. ls_coa_details-internal_order = '*'. ls_coa_details-wbs_element = '*'. ls_coa_details-manager_id = lv_manager_id. "For new entries, Manager Id is the same as that on existing COA entries for the user. APPEND ls_coa_details TO lt_coa_details. ENDLOOP. " Ignore the message IF ( lo_cx_coa_user IS NOT INITIAL or lo_coa_user->is_deleted( ) ) " The user is deleted or does not exist AND lt_coa_details IS INITIAL. " AND All the inbound records are deletions RETURN. " Ignore transaction - finish ok. ENDIF. " Raise missing user IF lo_cx_coa_user IS NOT INITIAL. RAISE EXCEPTION lo_cx_coa_user. ENDIF. " Updates IF lo_coa_user->is_deleted( ). " User &1 is deleted. COA cannot be updated. ""**** ZCX_FEH EXCEPTION RAISED HERE ***** ENDIF. lo_coa_user->set_coa_details( lt_coa_details[] ). lo_coa_user->save( ). CATCH zcx_opentext_service INTO lo_cx_opentext. "**** ZCX_FEH EXCEPTION RAISED HERE ***** ENDTRY. ENDMETHOD. |
Local Test Class |
---|
CLASS ltc_process DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS FINAL. PRIVATE SECTION. METHODS: setup. METHODS: test_2auth FOR TESTING. * METHODS: test_2auth_1obsolete FOR TESTING. * METHODS: test_missinguser_coadeletions FOR TESTING. * METHODS: test_update_on_deleted_user FOR TESTING. * METHODS: test_opentext_error FOR TESTING. DATA : mo_coa_user TYPE REF TO zif_opentext_vim_coa_user. CLASS-DATA : mo_coa_user_factory TYPE REF TO zif_vim_coa_user_factory. DATA : mo_si_opentext_delegauth_bulk TYPE REF TO ycl_si_opentext_coa. ENDCLASS. CLASS ltc_process IMPLEMENTATION. METHOD setup. mo_si_opentext_delegauth_bulk ?= ycl_si_opentext_coa=>s_create( iv_context = zcl_feh_framework=>gc_context_external ). ENDMETHOD. METHOD test_2auth . *----------------------------------------------------------------------* * This tests the scenario where the user has 2 authority records * * and both are saved properly. * *----------------------------------------------------------------------* DATA ls_process_data TYPE zopentext_deleg_auth_process_s. DATA ls_coa_details_process TYPE zopentext_coa_detl_process_s. DATA lt_coa_details TYPE zopentext_coa_details_tt. DATA ls_coa_details TYPE LINE OF zopentext_coa_details_tt. "config the test double call to manager id mo_coa_user ?= cl_abap_testdouble=>create( 'ZIF_OPENTEXT_VIM_COA_USER' ). cl_abap_testdouble=>configure_call( mo_coa_user )->returning( 'WILLIA60' ). mo_coa_user->get_manager_id( ). " expected results ls_coa_details-counter = 1. ls_coa_details-currency = 'NZD'. ls_coa_details-approval_limit = 200. ls_coa_details-expense_type = 'CP'. ls_coa_details-bukrs = '*'. ls_coa_details-kostl = '*'. ls_coa_details-internal_order = '*'. ls_coa_details-wbs_element = '*'. ls_coa_details-manager_id = 'WILLIA60'. APPEND ls_coa_details TO lt_coa_details. ls_coa_details-counter = 2. ls_coa_details-currency = 'NZD'. ls_coa_details-approval_limit = 300. ls_coa_details-expense_type = 'SR'. ls_coa_details-bukrs = '*'. ls_coa_details-kostl = '*'. ls_coa_details-internal_order = '*'. ls_coa_details-wbs_element = '*'. ls_coa_details-manager_id = 'WILLIA60'. APPEND ls_coa_details TO lt_coa_details. "configure the expected behavior of the set_coa_details( ) cl_abap_testdouble=>configure_call( mo_coa_user )->and_expect( )->is_called_times( 1 ). mo_coa_user->set_coa_details( lt_coa_details ). " Inject the test double into the factory which will be used inside the method under test. TRY. zcl_vim_coa_user_factory=>get_instance( )->set_coa_user( mo_coa_user ). CATCH zcx_opentext_service ##no_handler. ENDTRY. " SETUP - INPUTS To the Method under test ls_process_data-windows_id = 'COAUSER'.
ls_coa_details_process-currency = 'NZD'. ls_coa_details_process-approval_limit = 200. ls_coa_details_process-expense_type = 'CP'. ls_coa_details_process-bukrs = '1253'. ls_coa_details_process-start_date = '20060328'. ls_coa_details_process-end_date = '29990328'. APPEND ls_coa_details_process TO ls_process_data-coa_details. ls_coa_details_process-currency = 'NZD'. ls_coa_details_process-approval_limit = 300. ls_coa_details_process-expense_type = 'SR'. ls_coa_details_process-bukrs = '1253'. ls_coa_details_process-start_date = '20060328'. ls_coa_details_process-end_date = '29990328'. APPEND ls_coa_details_process TO ls_process_data-coa_details. " EXECUTE the method under test TRY. mo_si_opentext_delegauth_bulk->zif_feh~process( is_process_data = ls_process_data ). CATCH zcx_feh ##no_handler. ENDTRY. " Verify interactions on test double cl_abap_testdouble=>verify_expectations( mo_coa_user ). ENDMETHOD. ENDCLASS. |
Some Test Tools available in SAP_ABA 740
Test Summary - 1 test method successful |
---|
![]() |
Test Coverage - only 1 test >> so it's pretty poor |
---|
![]() |
Test Coverage - lots of untested code in red! |
---|
![]() |
(Sorry for the eclipse fans. I re-flashed my PC to 64 bit. I haven't had the chance to re-install my Eclipse tools. Those coverage tools are there too! ).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
3 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |