ABAP Forum
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

[Bug] in method cl_cds_test_environment=>create_for_multiple_cds

Sandra_Rossi
Active Contributor
503

There was a question in 2023 alleging a possible bug, proposing solutions, but there was no answer: [Bug] in method cl_cds_test_environment=>create_fo... - SAP Community.

I'm posting it again as the original question is now "read only".

That question was saying that the below code fails at line 3, when mixing CL_CDS_TEST_ENVIRONMENT=>CREATE_FOR_MULTIPLE_CDS and CL_OSQL_TEST_ENVIRONMENT=>CREATE:

cl_cds_test_environment=>create_for_multiple_cds( 
             i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT' ) ) ).
cl_osql_test_environment=>create( 
             i_dependency_list = VALUE #( ( 'MARA' ) ) ).

That question said there was no bug if using CREATE instead of CREATE_FOR_MULTIPLE_CDS of the class CL_CDS_TEST_ENVIRONMENT:

cl_cds_test_environment=>create( i_for_entity = 'I_PRODUCT' ).
cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).

That question was proposing 2 solutions to mock multiple CDS views:

  1. One targeted to SAP,  by inserting the test "IF test_associations EQ 'X' " in CREATE_MUL_CDS_TEST_INSTANCE, the same way it's done in CREATE_CDS_TEST_INSTANCE (NB: the question did not mention the ABAP version):
    Sandra_Rossi_0-1779270912128.png
  2. One workaround by removing MARA via CL_OSQL_REPLACE=>GET_ACTIVE_REPLACEMENTS and CL_OSQL_REPLACE=>ACTIVATE_REPLACEMENT between CDS and OSQL environment creations (code here: https://community.sap.com/khhcw49343/attachments/khhcw49343/application-developmentforum-board/20205...)

@burghard and others, any idea?

Thanks.

Sandra

1 ACCEPTED SOLUTION
Read only

Sandra_Rossi
Active Contributor
501

@burghard In ABAP 7.58 SP 1, I reproduce exactly the problems described and the SAP code is the same as described in the original question, BUT I don't agree with the analysis or it works differently in ABAP 7.58 SP 1:

  1. Two of the three test methods of the code attached still succeed as originally said, but they fail when using INSERT_TEST_DATA: "The test double 'I_PRODUCT' not found"", CX_CDS_FAILURE=>TEST_DOUBLE_NOT_FOUND in the method IF_CDS_TEST_ENVIRONMENT~GET_DOUBLE of CL_CDS_TEST_ENVIRONMENT.
    I post below the code of INSERT_TEST_DATA.
  2. The way the test doubles are used is incorrect, or it works differently in ABAP 7.58 SP 1.
    I propose below two scenarios how to use the CDS and OSQL test doubles.

How to use the CDS and OSQL test doubles:

  1. If I_PRODUCT and MARA are to be mocked independently, which make it possibly incoherent (querying I_PRODUCT returning one product A and querying MARA returning one product B for instance), there's no need to use CL_CDS_TEST_ENVIRONMENT, instead use CL_OSQL_TEST_ENVIRONMENT:
cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'I_PRODUCT' )
                                                               ( 'MARA' ) ) ).
  1. ---
  2. If mock data is to be injected in MARA and that should impact the CDS views based on MARA (I_PRODUCT), use only CL_CDS_TEST_ENVIRONMENT, not CL_OSQL_TEST_ENVIRONMENT, and enable the double redirection in order to make SELECT FROM MARA read the data:
m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
              i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT'
                                          i_select_base_dependencies = abap_true ) ) ).

" Explicit enabling of double redirection, although CREATE_FOR_MULTIPLE_CDS implicitly enables it.
m_cds_test_environment->enable_double_redirection( ).

 

Appendix

Full code, with test classes LCL_TEST_* from the original question + implementations of TEST methods by me + new test classes LTCL_MOCK_* which implement the 2 solutions above:

**********************************************************************
*
* The classes LCL_TEST_* are copied from this question (1st link), specifically this attachment (2nd link),
* but I have added an implementation to the method TEST to show that INSERT_TEST_DATA fails anyway:
* https://community.sap.com/t5/application-development-and-automation-discussions/bug-in-method-cl-cds-test-environment-gt-create-for-multiple-cds/td-p/12732251
* https://community.sap.com/khhcw49343/attachments/khhcw49343/application-developmentforum-board/2020507/2/reproducer.txt)
*
* The classes LTCL_MOCK_* are added by me, they work as desired in ABAP 7.58 SP 1.
*
**********************************************************************

**********************************************************************
* Classes LCL_TEST_*
**********************************************************************

** This is a test class to reproduce the error
** How to use:
** 1. Create a new class in the local package (you can give it any name)
** 2. Open the Test Classes section
** 3. Copy the code below
** 4. Execute unit tests.

** Expected result: all 3 tests should be green
** Actual result: One test is red.



*"* use this source file for your ABAP unit test classes


CLASS lcl_test_single DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS: test FOR TESTING.
  PRIVATE SECTION.
    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment .
    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment .
    CLASS-METHODS: class_setup.
ENDCLASS.

CLASS lcl_test_multi DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS: test FOR TESTING.
  PRIVATE SECTION.
    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment .
    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment .
    CLASS-METHODS: class_setup.
ENDCLASS.

CLASS lcl_test_multi_with_fix DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS: test FOR TESTING.
  PRIVATE SECTION.
    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment .
    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment .
    CLASS-METHODS: class_setup.
ENDCLASS.

CLASS lcl_test_single IMPLEMENTATION.

  METHOD test.
    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.

    DATA(injected_products) = VALUE ty_products( ( product = 'A' ) ).
    " INSERT_TEST_DATA fails "The test double 'I_PRODUCT' not found"
    " (CX_CDS_FAILURE=>TEST_DOUBLE_NOT_FOUND in the method IF_CDS_TEST_ENVIRONMENT~GET_DOUBLE of CL_CDS_TEST_ENVIRONMENT).
    m_cds_test_environment->insert_test_data( i_data = injected_products ).
  ENDMETHOD.

  METHOD class_setup.
    " this setup shows that creating a double for the CDS view I_PRODUCT, followed by creating a double for the MARA table is possible
    " when the (single) create method of cl_cds_test_environment is used.
    "
    m_cds_test_environment = cl_cds_test_environment=>create(  i_for_entity  = 'I_PRODUCT' ).
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).
  ENDMETHOD.

ENDCLASS.



CLASS lcl_test_multi IMPLEMENTATION.

  METHOD test.
  ENDMETHOD.

  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds( i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT' ) ) ).

    " CREATE below fails "Double/Clone cannot be created. Double/Clone already exists for 'MARA'"
    " (CX_OSQL_FAILURE=>DOUBLE_EXIST in the method VALIDATE_DOUBLES of CL_OSQL_TEST_ENVIRONMENT).
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).
  ENDMETHOD.

ENDCLASS.




CLASS lcl_test_multi_with_fix IMPLEMENTATION.
  METHOD test.
    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.

    DATA(injected_products) = VALUE ty_products( ( product = 'A' ) ).
    " INSERT_TEST_DATA fails "The test double 'I_PRODUCT' not found"
    " (CX_CDS_FAILURE=>TEST_DOUBLE_NOT_FOUND in the method IF_CDS_TEST_ENVIRONMENT~GET_DOUBLE of CL_CDS_TEST_ENVIRONMENT).
    m_cds_test_environment->insert_test_data( i_data = injected_products ).
  ENDMETHOD.


  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds( i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT' ) ) ).

    " the call to create_for_multiple_cds erroneously creates entries for MARFA and MAW1
    " in the cl_osql_replace replacement list.
    " We can work around this bug by removing the spurious entries as follows:
    DATA(lt_replacements) = cl_osql_replace=>get_active_replacements( ).

    LOOP AT lt_replacements INTO DATA(ls_replacement).
      IF ls_replacement-source = 'MARA' OR ls_replacement-source = 'MAW1'.
        DELETE lt_replacements.
      ENDIF.
    ENDLOOP.
    TRY.
        cl_osql_replace=>activate_replacement( replacement_table = lt_replacements ).
      CATCH cx_osql_replace INTO DATA(l_error).
        cl_abap_unit_assert=>assert_not_bound( act = l_error ).
    ENDTRY.

    " after the cl_osql_replace replacement list has been cleaned up, a test double for MARA can be created.
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).
  ENDMETHOD.

ENDCLASS.


**********************************************************************
* Classes LTCL_MOCK_*
**********************************************************************

CLASS ltcl_mock_cds_table_independen DEFINITION FINAL
  FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    METHODS test FOR TESTING RAISING cx_static_check.

    CLASS-METHODS class_setup.

    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment.

    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.
    TYPES ty_mara     TYPE STANDARD TABLE OF mara WITH EMPTY KEY.
ENDCLASS.

CLASS ltcl_mock_cds_table_independen IMPLEMENTATION.
  METHOD class_setup.
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'I_PRODUCT' )
                                                                                             ( 'MARA' ) ) ).
  ENDMETHOD.

  METHOD test.
    DATA(injected_products) = VALUE ty_products( ( product = 'A' ) ).
    m_osql_test_environment->insert_test_data( injected_products ).
    DATA(injected_mara) = VALUE ty_mara( ( mandt = sy-mandt matnr = 'B' ) ).
    m_osql_test_environment->insert_test_data( injected_mara ).

    SELECT *
      FROM i_product
      INTO TABLE @DATA(actual_products).
    cl_abap_unit_assert=>assert_equals( act = actual_products
                                        exp = injected_products ).
    SELECT *
      FROM mara
      INTO TABLE @DATA(actual_mara).
    cl_abap_unit_assert=>assert_equals( act = actual_mara
                                        exp = injected_mara ).
  ENDMETHOD.
ENDCLASS.

CLASS ltcl_mock_tables_only_multi DEFINITION FINAL
  FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    METHODS test FOR TESTING RAISING cx_static_check.

    CLASS-METHODS class_setup.

    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment.

    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.
    TYPES ty_mara     TYPE STANDARD TABLE OF mara WITH EMPTY KEY.
ENDCLASS.

CLASS ltcl_mock_tables_only_multi IMPLEMENTATION.
  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
                                 i_for_entities = VALUE #( ( i_for_entity               = 'I_PRODUCT'
                                                             i_select_base_dependencies = abap_true ) ) ).
    " Explicit enabling of double redirection, although CREATE_FOR_MULTIPLE_CDS implicitly enables it.
    m_cds_test_environment->enable_double_redirection( ).
  ENDMETHOD.

  METHOD test.
    DATA(injected_mara) = VALUE ty_mara( ( mandt = sy-mandt matnr = 'A' ) ).
    m_cds_test_environment->insert_test_data( injected_mara ).

    SELECT *
      FROM i_product
      INTO TABLE @DATA(actual_products).
    cl_abap_unit_assert=>assert_equals( act = actual_products
                                        exp = VALUE ty_products( ( product        = 'A'
                                                                   isactiveentity = abap_true ) ) ).
    SELECT *
      FROM mara
      INTO TABLE @DATA(actual_mara).
    cl_abap_unit_assert=>assert_equals( act = actual_mara
                                        exp = injected_mara ).
  ENDMETHOD.
ENDCLASS.

CLASS ltcl_mock_tables_only_single DEFINITION FINAL
  FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    METHODS test FOR TESTING RAISING cx_static_check.

    CLASS-METHODS class_setup.

    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment.

    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.
    TYPES ty_mara     TYPE STANDARD TABLE OF mara WITH EMPTY KEY.
ENDCLASS.

CLASS ltcl_mock_tables_only_single IMPLEMENTATION.
  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create( i_for_entity               = 'I_PRODUCT'
                                                             i_select_base_dependencies = abap_true ).
    " Explicit enabling of double redirection, because CREATE doesn't enable it implicitly.
    m_cds_test_environment->enable_double_redirection( ).
  ENDMETHOD.

  METHOD test.
    DATA(injected_mara) = VALUE ty_mara( ( mandt = sy-mandt matnr = 'A' ) ).
    m_cds_test_environment->insert_test_data( injected_mara ).

    SELECT *
      FROM i_product
      INTO TABLE @DATA(actual_products).
    cl_abap_unit_assert=>assert_equals( act = actual_products
                                        exp = VALUE ty_products( ( product        = 'A'
                                                                   isactiveentity = abap_true ) ) ).
    SELECT *
      FROM mara
      INTO TABLE @DATA(actual_mara).
    cl_abap_unit_assert=>assert_equals( act = actual_mara
                                        exp = injected_mara ).
  ENDMETHOD.
ENDCLASS.

 

View solution in original post

1 REPLY 1
Read only

Sandra_Rossi
Active Contributor
502

@burghard In ABAP 7.58 SP 1, I reproduce exactly the problems described and the SAP code is the same as described in the original question, BUT I don't agree with the analysis or it works differently in ABAP 7.58 SP 1:

  1. Two of the three test methods of the code attached still succeed as originally said, but they fail when using INSERT_TEST_DATA: "The test double 'I_PRODUCT' not found"", CX_CDS_FAILURE=>TEST_DOUBLE_NOT_FOUND in the method IF_CDS_TEST_ENVIRONMENT~GET_DOUBLE of CL_CDS_TEST_ENVIRONMENT.
    I post below the code of INSERT_TEST_DATA.
  2. The way the test doubles are used is incorrect, or it works differently in ABAP 7.58 SP 1.
    I propose below two scenarios how to use the CDS and OSQL test doubles.

How to use the CDS and OSQL test doubles:

  1. If I_PRODUCT and MARA are to be mocked independently, which make it possibly incoherent (querying I_PRODUCT returning one product A and querying MARA returning one product B for instance), there's no need to use CL_CDS_TEST_ENVIRONMENT, instead use CL_OSQL_TEST_ENVIRONMENT:
cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'I_PRODUCT' )
                                                               ( 'MARA' ) ) ).
  1. ---
  2. If mock data is to be injected in MARA and that should impact the CDS views based on MARA (I_PRODUCT), use only CL_CDS_TEST_ENVIRONMENT, not CL_OSQL_TEST_ENVIRONMENT, and enable the double redirection in order to make SELECT FROM MARA read the data:
m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
              i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT'
                                          i_select_base_dependencies = abap_true ) ) ).

" Explicit enabling of double redirection, although CREATE_FOR_MULTIPLE_CDS implicitly enables it.
m_cds_test_environment->enable_double_redirection( ).

 

Appendix

Full code, with test classes LCL_TEST_* from the original question + implementations of TEST methods by me + new test classes LTCL_MOCK_* which implement the 2 solutions above:

**********************************************************************
*
* The classes LCL_TEST_* are copied from this question (1st link), specifically this attachment (2nd link),
* but I have added an implementation to the method TEST to show that INSERT_TEST_DATA fails anyway:
* https://community.sap.com/t5/application-development-and-automation-discussions/bug-in-method-cl-cds-test-environment-gt-create-for-multiple-cds/td-p/12732251
* https://community.sap.com/khhcw49343/attachments/khhcw49343/application-developmentforum-board/2020507/2/reproducer.txt)
*
* The classes LTCL_MOCK_* are added by me, they work as desired in ABAP 7.58 SP 1.
*
**********************************************************************

**********************************************************************
* Classes LCL_TEST_*
**********************************************************************

** This is a test class to reproduce the error
** How to use:
** 1. Create a new class in the local package (you can give it any name)
** 2. Open the Test Classes section
** 3. Copy the code below
** 4. Execute unit tests.

** Expected result: all 3 tests should be green
** Actual result: One test is red.



*"* use this source file for your ABAP unit test classes


CLASS lcl_test_single DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS: test FOR TESTING.
  PRIVATE SECTION.
    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment .
    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment .
    CLASS-METHODS: class_setup.
ENDCLASS.

CLASS lcl_test_multi DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS: test FOR TESTING.
  PRIVATE SECTION.
    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment .
    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment .
    CLASS-METHODS: class_setup.
ENDCLASS.

CLASS lcl_test_multi_with_fix DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS: test FOR TESTING.
  PRIVATE SECTION.
    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment .
    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment .
    CLASS-METHODS: class_setup.
ENDCLASS.

CLASS lcl_test_single IMPLEMENTATION.

  METHOD test.
    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.

    DATA(injected_products) = VALUE ty_products( ( product = 'A' ) ).
    " INSERT_TEST_DATA fails "The test double 'I_PRODUCT' not found"
    " (CX_CDS_FAILURE=>TEST_DOUBLE_NOT_FOUND in the method IF_CDS_TEST_ENVIRONMENT~GET_DOUBLE of CL_CDS_TEST_ENVIRONMENT).
    m_cds_test_environment->insert_test_data( i_data = injected_products ).
  ENDMETHOD.

  METHOD class_setup.
    " this setup shows that creating a double for the CDS view I_PRODUCT, followed by creating a double for the MARA table is possible
    " when the (single) create method of cl_cds_test_environment is used.
    "
    m_cds_test_environment = cl_cds_test_environment=>create(  i_for_entity  = 'I_PRODUCT' ).
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).
  ENDMETHOD.

ENDCLASS.



CLASS lcl_test_multi IMPLEMENTATION.

  METHOD test.
  ENDMETHOD.

  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds( i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT' ) ) ).

    " CREATE below fails "Double/Clone cannot be created. Double/Clone already exists for 'MARA'"
    " (CX_OSQL_FAILURE=>DOUBLE_EXIST in the method VALIDATE_DOUBLES of CL_OSQL_TEST_ENVIRONMENT).
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).
  ENDMETHOD.

ENDCLASS.




CLASS lcl_test_multi_with_fix IMPLEMENTATION.
  METHOD test.
    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.

    DATA(injected_products) = VALUE ty_products( ( product = 'A' ) ).
    " INSERT_TEST_DATA fails "The test double 'I_PRODUCT' not found"
    " (CX_CDS_FAILURE=>TEST_DOUBLE_NOT_FOUND in the method IF_CDS_TEST_ENVIRONMENT~GET_DOUBLE of CL_CDS_TEST_ENVIRONMENT).
    m_cds_test_environment->insert_test_data( i_data = injected_products ).
  ENDMETHOD.


  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds( i_for_entities = VALUE #( ( i_for_entity = 'I_PRODUCT' ) ) ).

    " the call to create_for_multiple_cds erroneously creates entries for MARFA and MAW1
    " in the cl_osql_replace replacement list.
    " We can work around this bug by removing the spurious entries as follows:
    DATA(lt_replacements) = cl_osql_replace=>get_active_replacements( ).

    LOOP AT lt_replacements INTO DATA(ls_replacement).
      IF ls_replacement-source = 'MARA' OR ls_replacement-source = 'MAW1'.
        DELETE lt_replacements.
      ENDIF.
    ENDLOOP.
    TRY.
        cl_osql_replace=>activate_replacement( replacement_table = lt_replacements ).
      CATCH cx_osql_replace INTO DATA(l_error).
        cl_abap_unit_assert=>assert_not_bound( act = l_error ).
    ENDTRY.

    " after the cl_osql_replace replacement list has been cleaned up, a test double for MARA can be created.
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'MARA' ) ) ).
  ENDMETHOD.

ENDCLASS.


**********************************************************************
* Classes LTCL_MOCK_*
**********************************************************************

CLASS ltcl_mock_cds_table_independen DEFINITION FINAL
  FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    METHODS test FOR TESTING RAISING cx_static_check.

    CLASS-METHODS class_setup.

    CLASS-DATA m_osql_test_environment TYPE REF TO if_osql_test_environment.

    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.
    TYPES ty_mara     TYPE STANDARD TABLE OF mara WITH EMPTY KEY.
ENDCLASS.

CLASS ltcl_mock_cds_table_independen IMPLEMENTATION.
  METHOD class_setup.
    m_osql_test_environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'I_PRODUCT' )
                                                                                             ( 'MARA' ) ) ).
  ENDMETHOD.

  METHOD test.
    DATA(injected_products) = VALUE ty_products( ( product = 'A' ) ).
    m_osql_test_environment->insert_test_data( injected_products ).
    DATA(injected_mara) = VALUE ty_mara( ( mandt = sy-mandt matnr = 'B' ) ).
    m_osql_test_environment->insert_test_data( injected_mara ).

    SELECT *
      FROM i_product
      INTO TABLE @DATA(actual_products).
    cl_abap_unit_assert=>assert_equals( act = actual_products
                                        exp = injected_products ).
    SELECT *
      FROM mara
      INTO TABLE @DATA(actual_mara).
    cl_abap_unit_assert=>assert_equals( act = actual_mara
                                        exp = injected_mara ).
  ENDMETHOD.
ENDCLASS.

CLASS ltcl_mock_tables_only_multi DEFINITION FINAL
  FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    METHODS test FOR TESTING RAISING cx_static_check.

    CLASS-METHODS class_setup.

    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment.

    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.
    TYPES ty_mara     TYPE STANDARD TABLE OF mara WITH EMPTY KEY.
ENDCLASS.

CLASS ltcl_mock_tables_only_multi IMPLEMENTATION.
  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
                                 i_for_entities = VALUE #( ( i_for_entity               = 'I_PRODUCT'
                                                             i_select_base_dependencies = abap_true ) ) ).
    " Explicit enabling of double redirection, although CREATE_FOR_MULTIPLE_CDS implicitly enables it.
    m_cds_test_environment->enable_double_redirection( ).
  ENDMETHOD.

  METHOD test.
    DATA(injected_mara) = VALUE ty_mara( ( mandt = sy-mandt matnr = 'A' ) ).
    m_cds_test_environment->insert_test_data( injected_mara ).

    SELECT *
      FROM i_product
      INTO TABLE @DATA(actual_products).
    cl_abap_unit_assert=>assert_equals( act = actual_products
                                        exp = VALUE ty_products( ( product        = 'A'
                                                                   isactiveentity = abap_true ) ) ).
    SELECT *
      FROM mara
      INTO TABLE @DATA(actual_mara).
    cl_abap_unit_assert=>assert_equals( act = actual_mara
                                        exp = injected_mara ).
  ENDMETHOD.
ENDCLASS.

CLASS ltcl_mock_tables_only_single DEFINITION FINAL
  FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    METHODS test FOR TESTING RAISING cx_static_check.

    CLASS-METHODS class_setup.

    CLASS-DATA m_cds_test_environment TYPE REF TO if_cds_test_environment.

    TYPES ty_products TYPE STANDARD TABLE OF i_product WITH EMPTY KEY.
    TYPES ty_mara     TYPE STANDARD TABLE OF mara WITH EMPTY KEY.
ENDCLASS.

CLASS ltcl_mock_tables_only_single IMPLEMENTATION.
  METHOD class_setup.
    m_cds_test_environment = cl_cds_test_environment=>create( i_for_entity               = 'I_PRODUCT'
                                                             i_select_base_dependencies = abap_true ).
    " Explicit enabling of double redirection, because CREATE doesn't enable it implicitly.
    m_cds_test_environment->enable_double_redirection( ).
  ENDMETHOD.

  METHOD test.
    DATA(injected_mara) = VALUE ty_mara( ( mandt = sy-mandt matnr = 'A' ) ).
    m_cds_test_environment->insert_test_data( injected_mara ).

    SELECT *
      FROM i_product
      INTO TABLE @DATA(actual_products).
    cl_abap_unit_assert=>assert_equals( act = actual_products
                                        exp = VALUE ty_products( ( product        = 'A'
                                                                   isactiveentity = abap_true ) ) ).
    SELECT *
      FROM mara
      INTO TABLE @DATA(actual_mara).
    cl_abap_unit_assert=>assert_equals( act = actual_mara
                                        exp = injected_mara ).
  ENDMETHOD.
ENDCLASS.