Skip to Content
Author's profile photo Nabheet Madan

ABAP Unit Test for Odata Services

Blogs in the Series

 

So continuing the ABAP Unit Test momentum from previous blog, we have managed to create ABAP Unit test for Odata services. The intent of this blog is to describe how to create local unit test classes for Odata services.

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. On googling found a SAP Help which actually talked unit test integration and implementing a method to get the request context

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.I hope this basic blog will help in implementing local test classes for all Odata services. Feel free to provide your feedback.

Assigned Tags

      20 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michelle Crapo
      Michelle Crapo

      OK - this is another one I'm going to add to our system.

      Thank you for sharing it!

      Michelle

       

      Author's profile photo Sérgio Fraga
      Sérgio Fraga

      Hello Nabheet,

      Thanks for this blog and for the motivation to jump into TDD when developing OData services.

      I would just like to add to everyone interesting in this topic that SAP provides a framework to automate tests in our OData developements.

      This framework is ECATT_ODATA, and it should help us definining automated tests for the OData services. I have tryed to explore a litlle but the tool, but I confess it's not simple to use. With the tool we get a wizard to create the tests with several options, but to my understaing the tool will generate the skeleton of the test classes where we should go there and add the testing code.

      The test clasees are global and they use the adition of FRIENDS to be able to access the *DPC_EXT and MPC_EXT clases.

      After some investigation I was not really convinved by the tool but nevertheless it's good to know it exists.

      If anyone has some good experience with this tool please share with us.

      Again, great work Nabheet. and I prefer your solution for doing Unit Testing in OData development.

      Thank you

      Sérgio Fraga

       

      Author's profile photo Nabheet Madan
      Nabheet Madan
      Blog Post Author

      Thanks for the feedback Sergio Fraga.This is what i like about blogging by sharing my thoughts about unit test script i came to know ECATT_Odata from you which am not aware.  Let me try to understand the framework and how it works.   Lets keep learning and keep sharing our experience does not matter how small they are.

      Author's profile photo Sérgio Fraga
      Sérgio Fraga

      Hello again Nabheet Madan ,

      I am using your approach with one of my OData developments and now I can test my code without using Gateway Client transaction!

      Using Unit Tests give me the confidance that the code is working as expected and it's much more fun to work like this.

      Thanks again for your investigation.

      I would just like to refer that you have a bug in your code.

      When you fill the PROPERTY of your LT_FILTER_SELECT_OPTIONS in your test code, your are passing the value of the import parameter IM_AUART.

      The test passes because in your productive code your are always reading the first line of the filter, and in your example it's OK because you only have 1 filter, but if you had 2+ filters you should look at the filter PROPERTY, which in your case should be 'AUART', since it's the value you have defined as the ABAP field in your SEGW project.

      Just a remark to make your code bullet proof 🙂

      I would also suggest to create a repo in abapGit with your example so that anyone could pull the code and test it right away. abapGit is an amazing project and we should make use of it.

      Have a great day

      Sérgio Fraga

       

       

       

       

       

      Author's profile photo Nabheet Madan
      Nabheet Madan
      Blog Post Author

      Thanks Sergio for the feedback. Agreed was trying to demonstrate the MVP in quick time so missed it will update.

      One small request can you please all share your experience of TDD where you have used it will help us?

      Thanks

      Nabheet

       

      Author's profile photo Sérgio Fraga
      Sérgio Fraga

      Hello again,

      My biggest advice is to read the book from Kent Beck, the father of TDD: Test Driven Development by Example

      Regarding OData Test Units,  I am having a problem and I would like to ask you if you know how to solve it.

      In your example, in the productive code you are using the table IT_FILTER_SELECT_OPTIONS. This table comes with the properties filled with the names of the entity properties defined in the SEGW project:

      Normally, when we use filters in OData Development, we should use the following method to extract the filters used in the request. This method will return a table with the ABAP Fields in the property and not with the names:

      *    "Get filter or select option information
          data(filter_select_options) = io_tech_request_context->get_filter( )->get_filter_select_options( ).

      The problem I am having is that if I use the method above to extract the filters from the request, when I am running the Unit Test I will have a dump, because in the get_filter( ) method there is a call to the get_entity_type() method of the service model, and it seems that in Unit Test context, the service model is not instantiated.

        METHOD /iwbep/if_mgw_req_entityset~get_filter.
      
          DATA: lo_filter_org  TYPE REF TO /iwbep/cl_mgw_req_filter.
      
      * Set Key Converter for Filter
          lo_filter_org ?= mo_filter.
          TRY.
              DATA: lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_fw_etype.
      
              CALL METHOD mo_model->get_entity_type "->MO_MODEL is not instantiated!!
                EXPORTING
                  iv_entity_name = mr_request->*-technical_request-target_entity_type
                RECEIVING
                  ro_entity_type = lo_entity_type.
      
              CALL METHOD lo_filter_org->set_entity_type
                EXPORTING
                  io_entity_type = lo_entity_type.
      
            CATCH /iwbep/cx_mgw_med_exception .
              EXIT.
          ENDTRY.
          ro_filter = mo_filter.
      
        ENDMETHOD.

      If you change your productive code to call the get_filter_select_options() instead of using IT_FILTER_SELECT_OPTIONS you will get the same issue.

      Does anyone have an ideia on how to solve this?

      Currently I am using the IT_FILTER_SELECT_OPTIONS and instead of using the ABAP field names to extract the correct filters from this table I am using the Entity Property names but I think we should always work with the ABAP field names since we are working in the backend service.

      Thanks a lot for any suggestion

      Sérgio Fraga

      Author's profile photo Alexander Chan
      Alexander Chan

      Sergio, it seems like the ms_request_context_struct which is of type

      TYPE /IWBEP/CL_MGW_REQUEST_UNITTST=>TY_S_MGW_REQUEST_CONTEXT_UNIT

      has the ability to set the parameters.

      ```

      " 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 ).

      ```

      Author's profile photo Venkat dattatreya
      Venkat dattatreya

      Hi Siergo,

       

      Redefine your /IWBEP/IF_MGW_CONV_SRV_RUNTIME~INIT_DP_FOR_UNIT_TEST method in DPC_EXT with below code, then it will work.

       

      / DATAlr_request_context  TYPE REF TO /iwbep/cl_mgw_request_unittst=>ty_s_mgw_request_context_unit.
      DATAlt_headers          TYPE        tihttpnvp.
      DATAlo_context          TYPE REF TO /iwbep/if_mgw_context.
      DATAlo_logger           TYPE REF TO /iwbep/cl_cos_logger.
      DATAlo_msg_container    TYPE REF TO /iwbep/if_message_container.
      DATAlo_msg_container_fw TYPE REF TO /iwbep/cl_mgw_msg_container.
      DATA lo_model             TYPE REF TO /iwbep/if_mgw_odata_fw_model.

      *---  INIT_DP_FOR_UNIT_TEST redefined to create model
      DATA(lo_metadata_provider/iwbep/cl_mgw_med_provider=>get_med_provider).

      TRY.
      lo_model ?= lo_metadata_provider->get_service_metadata(
      iv_internal_service_name    = <ODATA SERVICE NAME  = *_SRV>

      iv_internal_service_version = <ODATA VERSION NO>
      ).
      CATCH /iwbep/cx_mgw_med_exception.
      RETURN.
      ENDTRY.

      ASSERT mr_request_details IS INITIAL.

      GET REFERENCE OF is_request_context INTO lr_request_context.
      ro_request_context NEW /iwbep/cl_mgw_request_unittst(

      it_headers lt_headers
      io_model   lo_model ).

      ro_request_context->set_request_contextir_request_context lr_request_context ).

      lo_logger /iwbep/cl_cos_logger=>get_logger).
      lo_msg_container /iwbep/cl_mgw_msg_container=>get_mgw_msg_container).
      TRY.
      lo_msg_container_fw ?= lo_msg_container.
      lo_msg_container_fw->reset).
      CATCH cx_sy_move_cast_error.
      CLEAR lo_msg_container.
      ENDTRY.

      lo_context ?= NEW /iwbep/cl_mgw_context).

      lo_context->set_parameter(

      iv_name  /iwbep/if_mgw_context=>gc_param_msg_container
      iv_value lo_msg_container
      ).

      lo_context->set_parameter(

      iv_name  /iwbep/if_mgw_context=>gc_param_logger
      iv_value lo_logger
      ).

      mo_context lo_context.

      Author's profile photo Coder X
      Coder X

      Passing SERVICE_DOC_NAME and VERSION in /IWBEP/CL_MGW_REQUEST_UNITTST=>TY_S_MGW_REQUEST_CONTEXT_UNIT doesn't always seem to work.

       

      Assuming that the test class is a friend of your *DPC_EXT class.

      We've to set two parameters for the mo_model to be initialized.

      After the call to

      mo_cut->/iwbep/if_mgw_conv_srv_runtime~init_dp_for_unit_test( is_request_context = ls_request_context).

      We've to set the service name and version as below

      mo_cut->mo_context->set_parameter( iv_name = /iwbep/if_mgw_context=>gc_param_isn iv_value = '<your_service_name>' ).
      mo_cut->mo_context->set_parameter( iv_name = /iwbep/if_mgw_context=>gc_param_isv iv_value = '<version>' ). "<version> = 0001 if you are using version one or don't remember setting one

       

      NOTE: This way of writing OData AUnits is now obsolete (I think as of 2022) and you should consider using Local Client Proxy if you are on higher version of ABAP Stack.

      Author's profile photo Holger Polch
      Holger Polch

       

      Hi,

      does this also work for oData-Services that are generated based on corresponding CDS Views? The mid and long term way of implementing an oData service is potentially no longer manually coding via SEGW but modelling a corrsponding CDS View with the oData Annotation.

      BR,

      Holger

       

       

      Author's profile photo Nabheet Madan
      Nabheet Madan
      Blog Post Author

      Dear Holger

      We have two options here as per my understanding as i dont see any annotation provided in CDS which actually make sense.

      1. Option one is to use ECATT_Odata as mentioned in previous comments which will generate the framework and classes based on your CDS
      2. Manual one.

      Thanks

      Nabheet

      Author's profile photo Sérgio Fraga
      Sérgio Fraga

      Well,

      From the open SAP course "Writing Testable Code for ABAP" we discovered that SAP is delivering a ABAP CDS Test Double Framework 🙂

       

       

      Author's profile photo Alexander Chan
      Alexander Chan

      Thanks for pointing to that course.  Nice to see info about all the test doubles.  It's one way that the io_tech_request_context might be able to be mocked.

      Author's profile photo Former Member
      Former Member

      Hi Nabheet,

      Thank you for this excelent post!

      Can you atach a test example for "get_entity" implementation method? I don't know how to set the key.

      Thank you!!

      Author's profile photo Tobias Trapp
      Tobias Trapp

      Hi Nabheet,

      great work 🙂 I have another question: Do you see a chance to test the MPC_EXT class as well? The use case is to to test a redefinition of the define method.

      Best Regards,
      Tobias

      Author's profile photo Koen Boutsen
      Koen Boutsen

      Hello.

      Your odata method has an exporting parameter er_entity_set = lr_data.  The type of this element is 'data'.  Do you know how you can evaluate the content of the elements and properties of these elements ?

      I mean something like assertEquals( exp = 'Man' act = lr_data-gender ).  Is there any way of casting or converting that can be used ?

       

      Best Regards

      Koen

      Author's profile photo Andreas Kopp
      Andreas Kopp

      Hello Nabheet.

      Thank you for this example. I have a similar case where I want to pass filter parameters to the get_entityset method. The only difference is that I want to use the get_filter method of io_tech_request_context instead of it_filter_select_options.

      In the get_entityset method I use the following code to get the filters from the request:

      DATA(lo_filter) = io_tech_request_context->get_filter( ).
      DATA(lt_filter_select_options) = lo_filter->get_filter_select_options( ).

      So in the unit test I want to pass the filter like this:

      "Request Structure filled to get the corresponding request context.
      DATA 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
      DATA mo_request_context_object TYPE REF TO /iwbep/cl_mgw_request_unittst.
      
      " Fill the data set and entity names to be unit tested
      me->ms_request_context_struct-technical_request-source_entity_type = 'MyEntity'.
      me->ms_request_context_struct-technical_request-target_entity_type = 'MyEntity'.
      me->ms_request_context_struct-technical_request-source_entity_set = 'MyEntitySet'.
      me->ms_request_context_struct-technical_request-target_entity_set = 'MyEntitySet'.
      
      "set correct filter
      lt_filter_select_options = VALUE #(
      ( property = 'SAP_OBJECT_ID'
      select_options = VALUE #( ( sign = 'I' option = 'EQ' low = 'PR-1000' ) ) )
      ( property = 'SAP_OBJECT_TYPE'
      select_options = VALUE #( ( sign = 'I' option = 'EQ' low = 'BUS2001' ) ) )
      ).
      
      me->ms_request_context_struct-technical_request-filter_object =
      NEW /iwbep/cl_mgw_req_filter(
      iv_filter_string = |( ( SapObjectType eq 'BUS2001' ) and ( SapObjectId eq 'PR-1000' ) )|
      it_filter_select_options = 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 = me->ms_request_context_struct
      ).

      When I run the unit test, I get the following output (the messages are partly German):

      'Im ST-Program /IWBEP/ST_ANY_DATA ist bei der Serialisierung ein Fehler aufgetreten.' 
      ('There was an error with the serialization in the ST-program /IWBEP/ST_ANY_DATA')
      
      'Die Verwendung eines Referenztyps ist hier nicht unterstützt.' 
      ('The usage of a reference type is not supported here')

      Stack:

      Include: </IWBEP/ST_ANY_DATA============XT> Line: <7>
      Include: </IWBEP/CL_MGW_REQUEST_UNITTST=CM00E> Line: <18>
      Include: </IWBEP/CL_MGW_REQUEST_UNITTST=CM001> Line: <13> (SET_REQUEST_CONTEXT)
      Include: </IWBEP/CL_MGW_ABS_DATA========CM01E> Line: <18> (/IWBEP/IF_MGW_CONV_SRV_RUNTIME~INIT_DP_FOR_UNIT_TEST)

      How can I work in unit tests with the technical request context and filters?

      Kind regards
      Andreas

      Author's profile photo pavel sokolov
      pavel sokolov

      For those who have the same problem.

      Do not set references in ms_request_context_struct before the method init_dp_for_unit_test is called. Set them afterwards. The request initialization process includes some XSL transformation which can not deal with reference types.

      The references in the structure are:

      ms_request_context_struct-technical_request-converted_keys
      ms_request_context_struct-technical_request-conv_action_parameters
      ms_request_context_struct-technical_request-filter_object
      ms_request_context_struct-technical_request-key_converter

      The class /iwbep/cl_mgw_request_unittst have separate public methods for those parameters except the last one (key_converter).

      Sample:

      ms_request_context_struct-technical_request-target_entity_set = 'MyEntity'.
      " ...
      mo_request_context_object =
        mo_cut->/iwbep/if_mgw_conv_srv_runtime~init_dp_for_unit_test( ms_request_context_struct ).
      
      DATA(lref_converted_keys) = NEW zcl_my_mpc=>ts_myentity( field1 = 'value1'
                                                               field2 = 'value2' ).
      mo_request_context_object->set_converted_keys( lref_converted_keys  ).
      
      " The same approach for set_converted_parameters

       

      Unfortunately, /iwbep/cl_mgw_request_unittst doesn’t work with filter objects even though it has the setter for them (check the post above by Sergio Fraga).

      The possible option here is to use a wrapper class around /iwbep/cl_mgw_request_unittst to be able to redefine the method /iwbep/if_mgw_req_entityset~get_filter which will return the filter objects you wanted. And the filter objects themselves should be test doubled based on the interface /iwbep/if_mgw_req_filter as the standard filter implementation actively uses service model objects (incl. convertions etc.) which aren’t available in the context of this tests.

      Author's profile photo Vinayak Nath Singh
      Vinayak Nath Singh

      Does these tests use mock data?

      Author's profile photo Adam Krawczyk
      Adam Krawczyk

      Hi Nabheet Madan ,

      Thank you for sharing this blog, interesting. It really inspired me to think about unit tests for ODATA context. Earlier I tried to mock classes, it was too much work and I gave up. Now you show an easier way, great!

      This framework however was still too heavy for me as it requires extra development if we want to test complex filters, selects, and other elements of ODATA. So I built my own simple way of testing ODATA by entering ODATA URL directly.

      Let's share experience! My way for ODATA testing can be found in the blog here:

      https://blogs.sap.com/2021/09/23/abap-unit-tests-for-odata-requests/

      Cheers!
      Adam