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

Creating unit test data in the RAP context

felixw
Explorer
0 Kudos
1,103

Dear community,

I am having an error creating a unit test with RAP. I have the following developments objects:

  • Z_A_ENTITY_A => My database table for entity A
  • Z_R_ ENTITY_A => My CDS base view for entity A
  • Z_I_ENTITY_A => My CDS interface view for entity A
  •  Z_C_ENTITY_A => My CDS consumption view for entity A
  • The same objects for an entity B. Entity A has a 0…n relationship to entity B.

Now I want to create a simple unit test for an determination of the interface view in which test data for entity A and B is necessary. In my test class I create the test environment like the following:

 

 

 

cds_test_environment = cl_cds_test_environment=>     cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
                               VALUE #(
                                       ( i_for_entity = 'Z_I_ENTITY_A' )
                                       ( i_for_entity = 'Z_I_ENTITY_B')
                                     )
                             ).

DATA my_mock_data TYPE STANDARD TABLE OF Z_A_ENTITY_A.
" Fill my_mock_data with test data values
...
" Insert test data
cds_test_environment->insert_test_data( i_data = my_mock_data ).

 

 

 

The insert_test_data statement fails with the following message “The test double ‘Z_A_ENTITY_A’ not found.

When I change the create_for_multiple_cds statement to use the base views, it works. However, I need to test on interface view level. How is this possible? What can I change in order to enable this?

In the documentation of create_for_multiple_cds it says "This parameter should not be used while writing a unit test. For unit test, the framework will automatically evaluate the first level dependencies in the hierarchy and will create doubles for them". This seems like an explanation why it works when creating the test environment on base view level. However, all attempts from my side to fill the dependecy list manually failed. Also, to me it is not clear whether "hierarchy" here refers to the relationship between Entities (like Entity A and B) or the relationship between base views and consumption views.

Any help is highly appreciated!

 

 

Accepted Solutions (1)

Accepted Solutions (1)

MioYasutake
SAP Champion
SAP Champion
0 Kudos

@felixw 

CDS test double mocks data sources that are just one tier below the CDS view under test. In your case, as you want to test the Z_I_ views, change the data type of the mock data from the table type to the base entity type as shown below:

DATA my_mock_data TYPE STANDARD TABLE OF Z_R_ENTITY_A.

 

Answers (2)

Answers (2)

felixw
Explorer

I was finally able to solve the problem without by-passing the base view.

@MioYasutakeYou were right to set the parameter i_select_base_dependencies = abap_true. The error I did all along was that I set it only for Entity A not also entity B.

For completness sake, here the pseudo code:

cds_test_environment = cl_cds_test_environment=>     cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
                               VALUE #(
                                       ( i_for_entity = 'Z_I_ENTITY_A' i_select_base_dependencies = ABAP_TRUE )
                                       ( i_for_entity = 'Z_I_ENTITY_B' i_select_base_dependencies = ABAP_TRUE )
                                     )
                             ).

DATA my_mock_data TYPE STANDARD TABLE OF Z_A_ENTITY_A.
" Fill my_mock_data with test data values
...
" Insert test data
cds_test_environment->insert_test_data( i_data = my_mock_data ).
felixw
Explorer
0 Kudos

@MioYasutake 

Thanks very much for clarifying! I changed the code as suggested by you which works fine when adding the mock data. However, I have a consecutive problem when changing the mock data with a MODIFY ENTITIES statement. More precisely I want to add an Entity B using CREATE BY for the existing entity A and commit after that. The code looks like this now:

cds_test_environment = cl_cds_test_environment=>     cds_test_environment = cl_cds_test_environment=>create_for_multiple_cds(
                               VALUE #(
                                       ( i_for_entity = 'Z_I_ENTITY_A' )
                                       ( i_for_entity = 'Z_I_ENTITY_B')
                                     )
                             ).

DATA my_mock_data TYPE STANDARD TABLE OF Z_R_ENTITY_A.
" Fill my_mock_data with test data values
...
" Insert test data
cds_test_environment->insert_test_data( i_data = my_mock_data ).

" Add new entity
      MODIFY ENTITIES OF Z_I_ENTITY_A IN LOCAL MODE
          ENTITY ENTITY_A
          CREATE BY \_ENTITY_B
	     AUTO FILL CID
          FIELDS  ( BusinessDataField )
          WITH VALUE #( ( %tky-key_field = my_mock_data[ 1 ]-key_field %target = VALUE #( ( BusinessDataField = ‘A’ )  ) ) )
          FAILED DATA(failed_modify)
          REPORTED DATA(reported_modify)
          MAPPED DATA(mapped_modify).

“ Here failed_modify and reported_modify is empty, mapped data contains 1 entry and sy-subrc = 0. Thus COMMIT should be possible 
COMMIT ENTITIES.

 

The commit dumps now with the message:

Error analysis

The program has indicated exception "CX_CSP_ACT_INTERNAL" as the reason for the
termination:
SQL operation 'UPDATE' returned unexpected sy-subrc '4'.

Information on where terminated

The termination occurred in ABAP program or include "CL_CSP_ACT_SAVE_TO_DB=========CP", in "LIF_SINGLE_ENTITY_HANDLER~PERFORM_DB_OPERATIONS". The
main program was "SAPMSSY4".

 

From what I can see in the debugger in LIF_SINGLE_ENTITY_HANDLER~PERFORM_DB_OPERATIONS  it looks to me like a new entry for Entity B is trying to be created (and then fails).

Remarks to the code above: The MODIFY Statement is normally in the method of my code under test. I just put it in the unit test for convenience. In both cases the dump is the same. The COMMIT is intended to be in my unit test.

MioYasutake
SAP Champion
SAP Champion
0 Kudos
@felixw I found the parameter 'i_select_base_dependencies' in the create method signature. By setting it to 'true', you can use base table types when creating test data.
felixw
Explorer
@MioYasutake Thanks a lot! I playe around with the parameters of create but did not mange to solve my problem. However, after I got rid of the base views (thus only using the table and the interfaceview) it worked as you suggested in your first answer. Thanks a lot