Skip to Content
Technical Articles

Calculate hash value for internal table

Introduction

This might not be groundbreaking tech-news, but it could benefit someone diving into ABAP unit testing for the first time.

From time to time the result of the method under test would be an internal table. And how to use this in the assertion for unit testing? Well, calculate the hash value for the entire internal table, and voila – assertion is possible.

 

Method to calculate hash value

METHODS:
  get_hash_value_for_itab
    IMPORTING
      it_table TYPE ANY TABLE
    EXPORTING
      ev_hash  TYPE hash160.
METHOD get_hash_value_for_itab.
    DATA: lv_string  TYPE xstring,
          lv_xbuffer TYPE xstring.

    " Clear the hash value
    CLEAR ev_hash.

    " Go through the table one line at a time
    LOOP AT it_table ASSIGNING FIELD-SYMBOL(<ls_line>).
      DATA(lv_index) = 0.
      CLEAR lv_string.

      " Concatenate all the columns of the line into one string
      DO.
        ASSIGN COMPONENT lv_index OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_field>) CASTING TYPE x.
        IF sy-subrc EQ 0.
          CONCATENATE lv_string <lv_field> INTO lv_string IN BYTE MODE.
          ADD 1 TO lv_index.
        ELSE.
          EXIT.
        ENDIF.
      ENDDO.

      " Add the string from the line to our buffer
      CONCATENATE lv_xbuffer lv_string INTO lv_xbuffer IN BYTE MODE.
    ENDLOOP.

    " Calculate the hash value for the entire buffer/table
    CALL FUNCTION 'CALCULATE_HASH_FOR_RAW'
      EXPORTING
        data           = lv_xbuffer
      IMPORTING
        hash           = ev_hash
      EXCEPTIONS
        unknown_alg    = 1
        param_error    = 2
        internal_error = 3
        OTHERS         = 4.
    IF sy-subrc <> 0.
      " Do error handling here
    ENDIF.
  ENDMETHOD.

Usage of method

DATA:
      lv_hash_old       TYPE hash160,
      lv_hash_new       TYPE hash160.

   me->get_hash_value_for_itab(
      EXPORTING
        it_table = gt_final_req
      IMPORTING
        ev_hash = lv_hash_old ).

   IF lv_hash_old <> lv_hash_new.
     “ There's a difference
   ENDIF.

 

cl_aunit_assert=>assert_equals(
      act = lv_hash
      exp = '5CAF285B3FA1C3F971BBEEEE1D61EF9095B6F4CC'
      msg = 'Hash value for output not correct'
    ).

Conclusion

When I use this I first validate that the internal table I wish to calculate hash for is correct. Then in debug I fetch the hash value for the internal table, and hardcode this into my assertion.

 

5 Comments
You must be Logged on to comment or reply to a post.
  • Thanks for this nice utility. I’m not sure in which case it can be useful for the unit tests, but anyway it may be useful in a number of situations.

    Also, maybe using the following code is a little bit faster for serializing the internal table, but I don’t know if it can be used for a later hash comparison:

    EXPORT itab = it_table TO DATA BUFFER lv_xstring COMPRESSION OFF.
    • Hello Robert, thank you for your comment. My challenge here was that I did not have the two tables available at the same time, so I could not make the comparison directly with assert_equals method.

      BR, Jan