ABAP Test Double Framework versus mockA
I recently had the chance to have a look into SAP’s ABAP Test Double Framework. Previously, the main tool for mock object creation was mockA, which did a great job in my previous projects.
The Test Double Framework’s fake object creation is quite straight forward. Creating such an instance is handy and even allows you to use the native method call to specify the importing-parameters. Please see the blog post from SAP:
“create test double object
lo_currency_converter_double ?= cl_abap_testdouble=>create( ‘if_td_currency_converter’ ).
“configuration for stubbing method ‘convert’:
“step 1: set the desired returning value for the method call
cl_abap_testdouble=>configure_call( lo_currency_converter_double )->returning( 80 ).
“step 2: specifying which method should get stubbed
amount = 100
source_currency = ‘USD’
target_currency = ‘EUR’
The same test double configuration in mockA:
“create test double object
lo_currency_converter_double ?= zcl_mocka_mocker=>zif_mocka_mocker~mock( ‘if_td_currency_converter’ )->method( ‘convert’ )->with( i_p1 = 100 i_p2 = ‘USD’ i_p3 = ‘EUR’ )->returns( 80 )->generate_mockup( ).
As you can see, mockA doesn’t allow to verify whether you correctly supplied the method’s importing-parameters and method name at design time. This restriction applies for the Test Double Framework only for exporting and changing-parameters.
The only two disadvantages that I’ve recognized are
- checked exceptions need to be catched in a dummy TRY…CATCH…RETURN…ENDTRY-statement to avoid ATC messages
- the exporting- and returning parameters specification comes before the actual method call specification and configuration of the importing parameter. You need to get used to it, but it’s fine
Let the framework ignore importing parameters
The Test Double Framework allows you to separately ignore importing parameters by attaching “->ignore_parameter(…)” to your “configure_call(…)” method call. This feature is not yet existent in mockA. However, if you avoid the “->with(…)” method call in mockA completely, it will return the specified output in any case . This is equivalent to “->ignore_all_parameters(…)”.
Quite handy in the Test Double Framework. Just call
cl_abap_testdouble=>verify_expectations( lo_currency_converter_double ).
..and let the framework assert that your specified methods have been called as intended.
mockA requires you to store the mock creation object of type ZIF_MOCKA_MOCKER.
It allows you to verify method calls like this:
cl_abap_unit_assert=>assert_true( mo_mocker->method( ‘convert’ )->has_been_called_with( i_p1 = 100 i_p2 = ‘USD’ i_p3 = ‘EUR’ ) ).
The Test Double Framework allows you to pass custom matchers which will implement interaction verifications on the fake method input parameters. The interface is called if_abap_testdouble_matcher and it is very easy to implement. mockA does not offer such a concept.
mockA requires NW 7.01. The Test Double Framework requires NW 7.40.
mockA supports classes and interfaces, while the Test Double Framework supports interfaces only at the moment.
The Test Double Framework is a really nice mocking framework. It works very well and offers functionality, which mockA doesn’t offer. However, some drawbacks still exist, e.g. when you want to mock classes or work with NW releases lower than 7.40
I use mockA every single day - it is so vital to our unit testing efforts.
We're a LONG ways away from being able to upgrade to 7.40 so we'll be using mockA for a few years 🙂
thanks for the interesting comparison. When deciding on the general API design we looked at several frameworks and decided at the end that static type checks were most important for us. This should explain why we avoided the usage of strings for configuring calls.
One small note regarding your remark:
It is pretty much best practice to declare exceptions in the test method signature so that the ABAP Unit framework takes care of the exception handling. Usually, you only use try catch statements in test methods if you explicitly want to test the exception handling. I recommend the following signature.
methods my_test_method for testing raising cx_static_check
great, thanks a lot for the feedback! I agree, static type checks are a very clear advantage for the test double framework.
And declaring the exception cx_static_check in the unit test method sounds very neat, i'll Keep that in mind.