
ABAP Cloud - System Fields (Solution)
What might an ABAP Cloud solution look like to access system information and fields while remaining testable and open? Learn more here.
Table of contents
In this article, we look at a possible solution for using system information and how we designed it.
Introduction
In the last article, we looked at the system fields and the sources from which we can obtain certain information. There are the SY or SYST structure, the Context class, and the XCO libraries, which provide similar approaches. Currently, many developments simply use the system fields, but these will become partially obsolete with ABAP Cloud. The new classes also provide various information, but are not always complete. Likewise, implementation is not necessarily easy, and testability is usually limited by the design.
Design
In this chapter we will once again discuss the chosen design and the associated criteria.
Criteria
We therefore took a look at the current implementation and defined some criteria that we want to achieve with the solution:
- Central access point for system information
- Descriptive objects and methods
- Testability of the data (mocking)
- Documentation with hints
- Easy access (little configuration, simple methods)
Design
In the design, we use a Factory to create an instance for access. In this case, the factory can be reached via ZCL_SYST, and we have omitted the word "Factory" to keep the name as short as possible. The various methods are defined in the ZIF_SYST interface, and the various types are made available.
We currently provide a standard implementation called "DEFAULT". available; in principle, further implementations could be made.
Injector
You can provide test doubles via the injector without having to adapt the actual code. This allows us to achieve a testable design of the component. The above article only touched on the topic "Injector", but didn't explain it in detail. The injector has the ability to set a private attribute directly in the factory using a global friend relationship. This attribute is taken into account when creating the instance, which is why our double is used in the test case. The injector itself is marked FOR TESTING, which means it can only be used in ABAP Unit scenarios and won't accidentally run in production code.
Usage
In this chapter, we look at the use of the class and the connection to the ABAP unit test.
Example
For our example, we implement two methods that will perform various validations for us. The first method performs an authorization check and maps the SY-SUBRC to a Boolean value.
METHOD has_authority.
AUTHORITY-CHECK OBJECT 'S_APPL_LOG'
ID 'ACTVT' FIELD '02'.
RETURN xsdbool( zcl_syst=>create( )->return_code( ) = 0 ).
ENDMETHOD.
The second method checks for a user ID and if it is a specific user, then ABAP_TRUE is returned.
METHOD is_technical_user.
IF zcl_syst=>create( )->user_id( ) = 'TECHUSER'.
RETURN abap_true.
ELSE.
RETURN abap_false.
ENDIF.
ENDMETHOD.
In both cases, we return an instance of the implementation using the CREATE method of the ZCL_SYST class. Using this object, we can then access the corresponding field/information and return the contents.
ABAP Unit (TDF)
In the first unit test, we use SAP's Test Double Framework (TDF) and create a double to test the HAS_AUTHORITY method.
DATA(double) = CAST zif_syst( cl_abap_testdouble=>create( 'ZIF_SYST' ) ).
cl_abap_testdouble=>configure_call( double )->ignore_all_parameters( )->returning( 0 ).
double->return_code( ).
We can then insert this double via the injector and then run our test. The double is then returned at runtime.
zcl_syst_injector=>inject_syst( double ).
ABAP Unit (Double)
In the second step, we test the IS_TECHNICAL_USER method using a local test class as its implementation. We use PARTIALLY IMPLEMENTED so that we don't have to implement the entire interface, but only our method for the test.
CLASS ltd_system DEFINITION FOR TESTING.
PUBLIC SECTION.
INTERFACES zif_syst PARTIALLY IMPLEMENTED.
ENDCLASS.
CLASS ltd_system IMPLEMENTATION.
METHOD zif_syst~user_id.
RETURN 'TECHUSER'.
ENDMETHOD.
ENDCLASS.
The test method code is then much shorter, and we only need to create the double and pass it into processing via the injector. We can then call and test the method as usual.
zcl_syst_injector=>inject_syst( NEW ltd_system( ) ).
ABAP Cloud
If you want to use the components in your development and you rely on different software components (SWCs), you must provide the implementation components with a C1 contract. Only then can the SWC artifacts be used across the system. The following objects must be released:
- Factory ZCL_SYST
- Interface ZIF_SYST
- Injector ZCL_SYST_INJECTOR
The actual implementation does not need to be released, as it is not used directly.
Functions
Here you will find a mapping of the various methods to the system fields and functions that we map with the class. One of the functions was implemented as an additional helper function. In most cases, however, the methods contain implementations from the XCO area that are also released for ABAP Cloud.
Method | Function |
---|---|
user_id | sy-uname |
user_alias | cl_abap_context_info=>get_user_alias |
system_date | sy-datum |
system_time | sy-uzeit |
timestamp | GET TIME STAMP |
timestamp_long | GET TIME STAMP |
utclong | utclong_current( ) |
user_date | sy-datlo |
user_time | sy-timlo |
time_zone | sy-zonlo |
language | sy-langu |
language_iso | - |
system_information | sy-mandt, sy-sysid, sy-cprog, sy-saprl |
index | sy-index |
table_index | sy-tabix |
database_count | sy-dbcnt |
return_code | sy-subrc |
letter_upper | sy-abcde |
letter_lower | - |
weekday | sy-fdayw |
message | sy-msgid, sy-msgno, sy-msgty, sy-msgv1, ... |
message_bapiret2 | sy-msgid, sy-msgno, sy-msgty, sy-msgv1, ... |
message_bali | sy-msgid, sy-msgno, sy-msgty, sy-msgv1, ... |
Hint: Currently, there is not a replacement for all fields, so the fields CPROG, SAPRL, and FDAYW are still included, which come directly from the system fields and thus generate a warning in the class.
Repository
You can find the mini-framework and some examples in the corresponding GitHub repository. There you will find all the objects and some further explanations about their structure. The example implementation and usage shown above can be found in the class ZCL_SYST_EXAMPLE.
Conclusion
Want to finally use system fields and mock their contents in your ABAP unit tests without any further adjustments? With our helper classes, this should now be possible without any further problems.