The intent of this blog is to describe how to create local unit test classes for Odata services.
In order to keep things simple we have created an Odata service which returns the description of the document type (AUART from TVAKT table) field based on the code passed to it. So I want to test my filter functionality where we will Document type code and it shall return description. In case no description exists then ABAP Unit test shall fail.
We used TVAKT table and created a service manually. Implemented the Get_Entityset method as shown below. The code simply returns the document type description based on the document type code passed to it.
Example Considered
In order to keep things simple we have created an Odata service which returns the description of the document type (AUART from TVAKT table) field based on the code passed to it. So I want to test my filter functionality where we will Document type code and it shall return description. In case no description exists then ABAP Unit test shall fail.
Gateway Service created in SEGW with TVAKT table.
We used TVAKT table and created a service manually. Implemented the Get_Entityset method as shown below. The code simply returns the document type description based on the document type code passed to it.
METHOD tvaktset_get_entityset.
DATA:lt_filters TYPE /iwbep/t_mgw_select_option,
ls_filter TYPE /iwbep/s_mgw_select_option,
ls_val TYPE /iwbep/s_cod_select_option.
READ TABLE it_filter_select_options INTO ls_filter INDEX 1.
IF sy-subrc EQ 0.
READ TABLE ls_filter-select_options INTO ls_val INDEX 1.
SELECT * FROM tvakt INTO TABLE et_entityset WHERE auart EQ ls_val-low AND spras = 'E'.
ENDIF.
ENDMETHOD.
ABAP Unit Test Class Definition
So we started by creating the unit test class for *DPC_EXT in the eclipse.
This class has 3 methods and 3 attributes
Attributes
1. CUT – referring to our DPC class
2. MS_REQUEST_CONTEXT_STRUCT requesting structure to get context object
3. MO_REQUEST_CONTEXT_OBJECT Object which will be passed to our DPC testing method.
Variable 2 and 3 were added after we faced an exception in our general flow explained below.
Methods
1. SETUP for our CUT object creation
2. GET_DOC_TYPE_TEXT for testing our different set of inputs.
3. RUN_FILTER basically contains reusable code to which test parameters are passed by GET_DOC_TYPE_TEXT method.
CLASS ltc_znabheet_dpc_ext DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT.
PRIVATE SECTION.
DATA:
" Request Structure filled to get the corresponding request context.
ms_request_context_struct TYPE /iwbep/cl_mgw_request_unittst=>ty_s_mgw_request_context_unit,
" Request context which is normally passed to each method call
mo_request_context_object TYPE REF TO /iwbep/cl_mgw_request_unittst,
" DPC referring to our extension call
cut TYPE REF TO zcl_znabheet_dpc_ext.
METHODS setup.
METHODS run_filter
IMPORTING
im_auart TYPE string
im_entity TYPE string
im_entityset TYPE string.
METHODS get_doc_type_text FOR TESTING RAISING cx_static_check.
ENDCLASS.
ABAP Unit Test Class Implementation
In method GET_DOC_TYPE_TEXT we call our RUN_FILTER method for each pair of inputs. In RUN_FILTER method we first tried to fill the Filter internal table and call GET_ENTITYSET method with just filter table with a hope that it will return us the searched values. Sadly it did not work, we were thrown an exception.
CLASS ltc_znabheet_dpc_ext IMPLEMENTATION.
"Created our data provider
METHOD setup.
CREATE OBJECT cut.
ENDMETHOD.
METHOD get_doc_type_text.
" Run valid Test
run_filter( EXPORTING im_auart = 'AG' im_entity = 'TVAKT' im_entityset = 'TVAKTSet' ).
" Run Invalid test
"run_filter( EXPORTING im_auart = 'ZZ' im_entity = 'TVAKT' im_entityset = 'TVAKTSet').
ENDMETHOD.
METHOD run_filter.
DATA: lt_filter_select_options TYPE /iwbep/t_mgw_select_option,
ls_filter_select_option TYPE /iwbep/s_mgw_select_option,
lt_filter TYPE /iwbep/t_cod_select_options,
ls_filter TYPE /iwbep/s_cod_select_option,
lr_data TYPE REF TO data,
ls_context TYPE /iwbep/if_mgw_appl_srv_runtime=>ty_s_mgw_response_context.
FIELD-SYMBOLS: <tab> TYPE table.
" Fill the filter field detail
ls_filter-sign = 'I'.
ls_filter-option = 'EQ'.
ls_filter-low = im_auart.
APPEND ls_filter TO lt_filter.
ls_filter_select_option-property = im_auart.
ls_filter_select_option-select_options = lt_filter.
APPEND ls_filter_select_option TO lt_filter_select_options.
"read data
TRY .
cut->/iwbep/if_mgw_appl_srv_runtime~get_entityset(
EXPORTING
io_tech_request_context = mo_request_context_object
it_filter_select_options = lt_filter_select_options " Table of select options
IMPORTING
er_entityset = lr_data
es_response_context = ls_context
).
CATCH /iwbep/cx_mgw_busi_exception.
CATCH /iwbep/cx_mgw_tech_exception.
ENDTRY.
" If no data found for document type text then it is an exception
ASSIGN lr_data->* TO <tab>.
CALL METHOD cl_abap_unit_assert=>assert_not_initial
EXPORTING
act = <tab>. " Actual Data Object
ENDMETHOD.
ENDCLASS.
So that actually led us to something related to Request context parameter is missing.
ABAP Unit Test Class – Method INIT_DP_FOR_UNIT_TEST
SAP has provided a method named INIT_DP_FOR_UNIT_TEST in all DPC_EXT classes to support unit testing. This method initializes the data provider instance or request context which we will be using to pass to our service call.
We implemented this method before the service call and Bingo everything was working fine both for positive as well as negative test cases. Revised RUN_FILTER method.
METHOD run_filter.
DATA: lt_filter_select_options TYPE /iwbep/t_mgw_select_option,
ls_filter_select_option TYPE /iwbep/s_mgw_select_option,
lt_filter TYPE /iwbep/t_cod_select_options,
ls_filter TYPE /iwbep/s_cod_select_option,
lr_data TYPE REF TO data,
ls_context TYPE /iwbep/if_mgw_appl_srv_runtime=>ty_s_mgw_response_context.
FIELD-SYMBOLS: <tab> TYPE table.
" Fill the data set and entity names to be unit tested
ms_request_context_struct-technical_request-source_entity_type = im_entity.
ms_request_context_struct-technical_request-target_entity_type = im_entity.
ms_request_context_struct-technical_request-source_entity_set = im_entityset.
ms_request_context_struct-technical_request-target_entity_set = im_entityset.
" Fill the filter field detail
ls_filter-sign = 'I'.
ls_filter-option = 'EQ'.
ls_filter-low = im_auart.
APPEND ls_filter TO lt_filter.
ls_filter_select_option-property = im_auart.
ls_filter_select_option-select_options = lt_filter.
APPEND ls_filter_select_option TO lt_filter_select_options.
" Every DPC class now has INIT_DP_FOR_UNIT_TEST method which is used to provide a data
" instance which can be used for unit testing
mo_request_context_object = cut->/iwbep/if_mgw_conv_srv_runtime~init_dp_for_unit_test(
is_request_context = ms_request_context_struct
).
"read data
TRY .
cut->/iwbep/if_mgw_appl_srv_runtime~get_entityset(
EXPORTING
io_tech_request_context = mo_request_context_object
it_filter_select_options = lt_filter_select_options " Table of select options
IMPORTING
er_entityset = lr_data
es_response_context = ls_context
).
CATCH /iwbep/cx_mgw_busi_exception.
CATCH /iwbep/cx_mgw_tech_exception.
ENDTRY.
" If no data found for document type text then it is an exception
ASSIGN lr_data->* TO <tab>.
CALL METHOD cl_abap_unit_assert=>assert_not_initial
EXPORTING
act = <tab>. " Actual Data Object
ENDMETHOD.
Learning
In order to implement ABAP unit test, method INIT_DP_FOR_UNIT_TEST must be called to get the request context.
No comments:
Post a Comment