2023 Jul 31 4:31 PM
Hi experts,
I'm trying to use unit tests for writing access database tests, but I can't find a way to validate the correctness of inserted data. I'm using the ABAP SQL Test Double Framework : if_osql_test_environment.
I'm testing an insert method into the EKKO table, which is replace (with the framework) by the internal table MT_EKKO. While reading this table after the insert in the test environment, no new line is added. The test failed at my READ INDEX 2 on MT_EKKO. The insert return a sy-subrc of 0.
My goal is to check my new values in the MT_EKKO table to test in the future BAPI custom enhancement.
Is there a way to look up for data changes in the double table made with the framework?
REPORT.
CLASS lcl_test_bapi DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS .
PRIVATE SECTION.
CLASS-DATA:
mo_sql_env TYPE REF TO if_osql_test_environment.
DATA:
mt_ekko TYPE STANDARD TABLE OF ekko.
CLASS-METHODS:
class_setup,
class_teardown.
METHODS:
setup,
teardown,
test_insert FOR TESTING.
ENDCLASS.
CLASS lcl_test_bapi IMPLEMENTATION.
"Setup and teardown
METHOD class_setup.
mo_sql_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'EKKO' ) ) ).
ENDMETHOD.
METHOD class_teardown.
mo_sql_env->destroy( ).
ENDMETHOD.
METHOD setup.
mt_ekko = VALUE #( ( mandt = sy-mandt ebeln = '1111111111' bstyp = 'F' bsart = 'NB' aedat = '20230703' ernam = 'setup_method' ) ).
mo_sql_env->insert_test_data( mt_ekko ).
ENDMETHOD.
METHOD teardown.
CLEAR: mt_ekko.
mo_sql_env->clear_doubles( ).
ENDMETHOD.
"Test method
METHOD test_insert.
DATA ls_ekko TYPE ekko.
ls_ekko = VALUE #( mandt = sy-mandt ebeln = '1234567890' bstyp = 'F' bsart = 'NB' aedat = '20230101' ernam = 'FromInsert' ).
INSERT INTO ekko VALUES ls_ekko.
cl_abap_unit_assert=>assert_subrc( ).
READ TABLE mt_ekko INTO DATA(ls_test) INDEX 2.
cl_abap_unit_assert=>assert_subrc( msg = 'MT_EKKO doesn''t have a second line.' ). "Test failed here
cl_abap_unit_assert=>assert_equals(
EXPORTING
act = ls_test-ernam
exp = 'FromInsert' ).
ENDMETHOD.
ENDCLASS.
A good example of what I'm trying to do (with the MODIFY keyword) is the class LTC_TEST_DML_STMNTS from the package SABP_UNIT_DOUBLE_OSQL_DEMO. The downside of this approach is the code only check sy-subrc, and return the value to test. I will no be able to do that in my tests.
BR,
Antoine
2023 Aug 03 5:03 PM
I misunderstood how the ABAP SQL Double Framework works...
As shown here, and as sandra.rossi pointed out the framework create a temporary database rather than modifying the internal table given in the setup method (MT_EKKO in my example).
So, in order to read and check modified values, you have to make another select in the test method to assert modifications.
"Test method
METHOD test_insert.
DATA ls_ekko TYPE ekko.
ls_ekko = VALUE #( mandt = sy-mandt ebeln = '1234567890' bstyp = 'F' bsart = 'NB' aedat = '20230101' ernam = 'FromInsert' ).
INSERT INTO ekko VALUES ls_ekko.
cl_abap_unit_assert=>assert_subrc( ).
SELECT * FROM EKKO INTO TABLE @DATA(lt_ekko).
READ TABLE lt_ekko INTO DATA(ls_test) INDEX 2.
cl_abap_unit_assert=>assert_subrc( msg = 'MT_EKKO doesn''t have a second line.' ).
cl_abap_unit_assert=>assert_equals(
EXPORTING
act = ls_test-ernam
exp = 'FromInsert' ).
ENDMETHOD.
2023 Jul 31 7:20 PM
MANDT missing maybe?
mt_ekko = VALUE #( ( ebeln = '1234567890' bstyp = 'F' bsart = 'NB' aedat = '20230703' ernam = 'setup_method' ) ).
mo_sql_env->insert_test_data( mt_ekko ).
2023 Aug 01 8:24 AM
I forgot this one thanks. But even with the MANDT, nothing change. The subrc of INSERT still at 0, but the double (mt_ekko) still with only one line (from the setup method) in the debugger.
2023 Aug 01 1:50 PM
No issue in my ABAP 7.57 system, with this minimal reproducible example:
REPORT.
CLASS ltc_main DEFINITION
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS test FOR TESTING.
CLASS-DATA mo_sql_env TYPE REF TO if_osql_test_environment.
DATA mt_ekko TYPE STANDARD TABLE OF ekko.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS setup.
ENDCLASS.
CLASS ltc_main IMPLEMENTATION.
METHOD class_setup.
mo_sql_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( 'EKKO' ) ) ).
ENDMETHOD.
METHOD setup.
mt_ekko = VALUE #( ( ebeln = '1234567890' ) ).
mo_sql_env->clear_doubles( ).
mo_sql_env->insert_test_data( mt_ekko ).
ENDMETHOD.
METHOD test.
DATA: ls_ekko TYPE ekko.
ls_ekko-mandt = sy-mandt.
ls_ekko-ebeln = '1234567890'.
sy-subrc = 0.
INSERT INTO ekko VALUES ls_ekko.
cl_abap_unit_assert=>assert_subrc( exp = 4 ).
ENDMETHOD.
METHOD class_teardown.
mo_sql_env->destroy( ).
ENDMETHOD.
ENDCLASS.
2023 Aug 01 2:56 PM
Thanks for your time and sorry for not being clear.
My insert test is also correct (the sy-subrc returned is 0 because no data exist with the same key) but the row newly inserted isn't in my internal table mt_ekko. As I'm trying to read a second line, this is where I got an error: on my READ TABLE INDEX 2.
My goal is to check my new values in the mt_ekko table to test in the future BAPI custom enhancement.
A good example of what I'm trying to do (with the MODIFY keyword) is the class LTC_TEST_DML_STMNTS from the package SABP_UNIT_DOUBLE_OSQL_DEMO. The code test if the price modification is correct. The problem, this test only checks the return price based on the MODIFY subrc :
" CUT
METHOD change_price.
DATA wa TYPE sflight.
SELECT SINGLE *
FROM sflight
INTO wa
WHERE carrid = carrid AND
connid = connid AND
fldate = fldate.
IF sy-subrc <> 0.
new_price = - 1.
RETURN.
ENDIF.
wa-price = wa-price * factor / 100.
MODIFY sflight FROM wa.
IF sy-subrc = 0.
new_price = wa-price.
ELSE.
new_price = - 2.
ENDIF.
ENDMETHOD.
" End CUT
" Test method (check the 10% discount has been made)
NEW cl_osql_dml_statements( )->change_price(
EXPORTING
carrid = 'ZZ'
connid = '1234'
fldate = sy-datum
factor = 90
IMPORTING new_price = DATA(new_price) ).
cl_aunit_assert=>assert_equals(
EXPORTING
exp = exp " Called with : invoke_and_assert( 360 )
act = new_price ).
"End test method
Where the modification takes place? As it's not visible on the double internal table, neither in the DB ... How to validate modified values?
2023 Aug 01 3:45 PM
What "double internal table" are you talking about? The concept of ABAP SQL Test Double is only in database.
Can't you ask a question with minimal reproducible code that we can copy and paste? (the same as I did)
Otherwise people will stop looking at your question if you give the important information only in the comments.
2023 Aug 03 3:00 PM
What "double internal table" are you talking about?
To what I understood, my MT_EKKO internal table replace the EKKO table while executing unit tests.
Can't you ask a question with minimal reproducible code that we can copy and paste?
I have rewritten my question to me clearer. I hope it's better.
2023 Aug 03 3:40 PM
To what I understood, my MT_EKKO internal table replace the EKKO table while executing unit tests.
Wrong. The database table is duplicated in the database under another name and is used instead of EKKO (NB: I'm not expert, I don't know what is exactly behind the scene).
2023 Aug 03 5:07 PM
I just figured it out what you was saying.
Thanks for your answers and your time. I submit an answer with a minimal explanation on what to do to solve this.
2023 Aug 03 5:03 PM
I misunderstood how the ABAP SQL Double Framework works...
As shown here, and as sandra.rossi pointed out the framework create a temporary database rather than modifying the internal table given in the setup method (MT_EKKO in my example).
So, in order to read and check modified values, you have to make another select in the test method to assert modifications.
"Test method
METHOD test_insert.
DATA ls_ekko TYPE ekko.
ls_ekko = VALUE #( mandt = sy-mandt ebeln = '1234567890' bstyp = 'F' bsart = 'NB' aedat = '20230101' ernam = 'FromInsert' ).
INSERT INTO ekko VALUES ls_ekko.
cl_abap_unit_assert=>assert_subrc( ).
SELECT * FROM EKKO INTO TABLE @DATA(lt_ekko).
READ TABLE lt_ekko INTO DATA(ls_test) INDEX 2.
cl_abap_unit_assert=>assert_subrc( msg = 'MT_EKKO doesn''t have a second line.' ).
cl_abap_unit_assert=>assert_equals(
EXPORTING
act = ls_test-ernam
exp = 'FromInsert' ).
ENDMETHOD.