04-04-2011 2:40 PM
G'Day,
I suspect there's no right or wrong, but interested in people's opinions on whether class constants should be re-used or hardcoded in an ABAPUnit test?
e.g.: I have a class ZCL_MYCLASS with a constant FOO, value 'BAR'.
In my unit test should we do:
...
if lv_test = zcl_myclass=>foo.
or
constants: lc_foo type string value 'BAR'.
...
if lv_test = lc_foo.
As I see it, the first keeps management of constants in one place, and you don't need to update your unit test if constants change. The second on the other hand tests that your constants are correct, as well as guarding against people modifying constants with unintended consequences.
Hmmm.... both valid cases. The question is whether the validity and/or unauthorised alteration of constants should be the subject of a unit test?
Opinions?
04-04-2011 3:16 PM
I would go for your first option, with the class.
like you said it yourself: " the first keeps management of constants in one place, and you don't need to update your unit test if constants change"
If the constant in your class changes, so will your unit test. I don't think you want to do a unit test with a constant that is different then the one specified in your class.
And if people change the value of the constant... Well you should do a unit test on that also.
Well that is my opinion.
grtz
Tom
04-04-2011 5:11 PM
Interesting idea, a separate test to verify that the constants are what my tests assume them to be. So we would add:
methods: check_constants for testing.
...
method check_constants.
cl_aunit_assert=>assert_equals( act = zcl_myclass=>foo
exp = 'BAR'
msg = 'Constants changed!' ).
endmethod.
I like it! Probably overkill for many cases, but useful for complex classes or where constants are used for hardcoding config data.
Thanks,
Mike
04-14-2011 6:45 PM
If you go with option 1, you would end-up creating test to verify the validity of the constant, which could be overkill and unnecessary ...
If you go with Option 2, your test would automatically take care of the situation when Constant changes.
E.g. I have a method, to do something when Order type is ZORD. This method takes the input as the Order type. So, even if the Constant changes, my test would fail as it always expects to have ZORD.
method get_order_data.
if iv_order_type = zif_main_c=>c_order_type.
....
return = me->t_data.
endif.
endmethod.
Test method:
method check_get_order_Data.
lt_Data_act = o_main->get_order_Data( 'ZORD' ).
cl_aunit_assert=>assert_equals( act = LT_DATA_ACT
exp = T_DATA_EXP
msg = 'Nothing found !' ).
endmethod.
So, as TDD says, you should change the test first to manifest the error and than change your production method. This will by itself make sure its validity when we change the constant.
Regards,
Naimesh Patel
04-19-2011 3:34 AM
Hi Mike, interesting question.
I always create an interface for types and another for constants (something like this is very common on Java Frameworks).
You can also create a local class/interface inside the include of the test class to keep all constants . In this way, you keep them centralized and avoid a change in business logic impact the tests.
See ya,