2019 Feb 12 8:48 PM
I am working on ABAP unit test. There is a method that imports some parameters and then update a database table. how can I test whether the update of this method is successful? Thank you!
2019 Feb 12 9:13 PM
On 7.5x (where x = 2, I think), there's a way of telling the kernel this is a test, and instead of writing to the actual database, it reads and writes to an area of memory (entirely transparently to you) instead.
Before then:
I create a local interface lif_db_accessor. I define methods that mirror the sql statements. So for
SELECT field1 field2 FROM table INTO some_Structure WHERE field3 = some_value and field4 = some_other_value,I have a method:
METHOD get_stuff
IMPORTING i_field1 TYPE ... i_field2 TYPE... i_field3 TYPE ... i_field 4 TYPE ...
RETURNING (VALUE) r_something TYPE some_structure.Then I implement lif_db_accessor in a local class lcl_db_accessor with the actual SQL.
For my main class, I define
CLASS-DATA _db_accessor TYPE REF TO lif_db_accessor.You'll need somewhere (look it up)
INTERFACE lif_db_accessor DEFERRED.in the class_constructor I have a statement.
_db_accessor = new zcl_db_accessor( ).Now, you need to make your ltc_test_main test class a LOCAL FRIEND of your main class.
Create a test double ltd_db_accessor that implement lif_db_accessor. Here, you implement all the methods of the interface, but instead of to a db table, to an internal table. So if it was MARA, you'd have something like.
CLASS ltd_db_accessor DEFINITION.
PUBLIC SECTION.
INTERFACE lif_db_accessor.
DATA db TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.ENDCLASS.
CLASS ltd_db_accessor IMPLEMENTATION.
METHOD lif_db_accessor~get_mtart.
" SELECT SINGLE mtart FROM MARA INTO r_mtart WHERE matnr EQ i_matnr.
READ TABLE db INTO data(db_Record) WITH TABLE KEY matnr = i_matnr.
r_mtart = db_Record-mtart.
ENDMETHOD.
ENDCLASS.In the definition of your test class you have
DATA:
cut TYPE REF TO main class.
db TYPE REF TO ltd_db_accessor.In the setup method you have
me->cut = new #( ).
me->db = new #( ).
me->cut->_db_accessor = me->db.
me->db = value #( ...db values... ).Now, whenever your code under test use the db accessor, instead of using lcl_db_accessor and getting data from the database, it will get the data from your ltd_db_accessor db attribute.
I'm preparing a blog on this very subject as I've been doing the above rather a lot recently.
On 7.5x (where x = 2, I think), there's a way of telling the kernel this is a test, and instead of writing to the actual database, it reads and writes to an area of memory (entirely transparently to you) instead.
Before then:
I create a local interface lif_db_accessor. I define methods that mirror the sql statements. So for
SELECT field1 field2 FROM table INTO some_Structure WHERE field3 = some_value and field4 = some_other_value,I have a method:
METHOD get_stuff
IMPORTING i_field1 TYPE ... i_field2 TYPE... i_field3 TYPE ... i_field 4 TYPE ...
RETURNING (VALUE) r_something TYPE some_structure.Then I implement lif_db_accessor in a local class lcl_db_accessor with the actual SQL.
For my main class, I define
CLASS-DATA _db_accessor TYPE REF TO lif_db_accessor.You'll need somewhere (look it up)
INTERFACE lif_db_accessor DEFERRED.in the class_constructor I have a statement.
_db_accessor = new zcl_db_accessor( ).Now, you need to make your ltc_test_main test class a LOCAL FRIEND of your main class.
Create a test double ltd_db_accessor that implement lif_db_accessor. Here, you implement all the methods of the interface, but instead of to a db table, to an internal table. So if it was MARA, you'd have something like.
CLASS ltd_db_accessor DEFINITION.
PUBLIC SECTION.
INTERFACE lif_db_accessor.
DATA db TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.ENDCLASS.
CLASS ltd_db_accessor IMPLEMENTATION.
METHOD lif_db_accessor~get_mtart.
" SELECT SINGLE mtart FROM MARA INTO r_mtart WHERE matnr EQ i_matnr.
READ TABLE db INTO data(db_Record) WITH TABLE KEY matnr = i_matnr.
r_mtart = db_Record-mtart.
ENDMETHOD.
ENDCLASS.In the definition of your test class you have
DATA:
cut TYPE REF TO main class.
db TYPE REF TO ltd_db_accessor.In the setup method you have
me->cut = new #( ).
me->db = new #( ).
me->cut->_db_accessor = me->db.
me->db = value #( ...db values... ).Now, whenever your code under test use the db accessor, instead of using lcl_db_accessor and getting data from the database, it will get the data from your ltd_db_accessor db attribute.
I'm preparing a blog on this very subject as I've been doing the above rather a lot recently.
2019 Feb 12 9:13 PM
On 7.5x (where x = 2, I think), there's a way of telling the kernel this is a test, and instead of writing to the actual database, it reads and writes to an area of memory (entirely transparently to you) instead.
Before then:
I create a local interface lif_db_accessor. I define methods that mirror the sql statements. So for
SELECT field1 field2 FROM table INTO some_Structure WHERE field3 = some_value and field4 = some_other_value,I have a method:
METHOD get_stuff
IMPORTING i_field1 TYPE ... i_field2 TYPE... i_field3 TYPE ... i_field 4 TYPE ...
RETURNING (VALUE) r_something TYPE some_structure.Then I implement lif_db_accessor in a local class lcl_db_accessor with the actual SQL.
For my main class, I define
CLASS-DATA _db_accessor TYPE REF TO lif_db_accessor.You'll need somewhere (look it up)
INTERFACE lif_db_accessor DEFERRED.in the class_constructor I have a statement.
_db_accessor = new zcl_db_accessor( ).Now, you need to make your ltc_test_main test class a LOCAL FRIEND of your main class.
Create a test double ltd_db_accessor that implement lif_db_accessor. Here, you implement all the methods of the interface, but instead of to a db table, to an internal table. So if it was MARA, you'd have something like.
CLASS ltd_db_accessor DEFINITION.
PUBLIC SECTION.
INTERFACE lif_db_accessor.
DATA db TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.ENDCLASS.
CLASS ltd_db_accessor IMPLEMENTATION.
METHOD lif_db_accessor~get_mtart.
" SELECT SINGLE mtart FROM MARA INTO r_mtart WHERE matnr EQ i_matnr.
READ TABLE db INTO data(db_Record) WITH TABLE KEY matnr = i_matnr.
r_mtart = db_Record-mtart.
ENDMETHOD.
ENDCLASS.In the definition of your test class you have
DATA:
cut TYPE REF TO main class.
db TYPE REF TO ltd_db_accessor.In the setup method you have
me->cut = new #( ).
me->db = new #( ).
me->cut->_db_accessor = me->db.
me->db = value #( ...db values... ).Now, whenever your code under test use the db accessor, instead of using lcl_db_accessor and getting data from the database, it will get the data from your ltd_db_accessor db attribute.
I'm preparing a blog on this very subject as I've been doing the above rather a lot recently.
2019 Feb 13 9:39 AM
What is your ABAP release? (from 7.52 there is the Open SQL Test Double Framework)
| User | Count |
|---|---|
| 3 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |