![]() To make it clearer, and with thanks to Jacques Nomssi here’s a nice UML diagram of what I did.Īnother approach that might have worked, would have been to define the test double as a local subclass of CL_SU01. Now that my test class is a friend of the CUT-class, all is syntactically correct, I can safely run my unit test in the knowledge that I’m not going to update any user accounts on the system. ![]() DEFINITION DEFERRED.ĬLASS zcl_cut_class DEFINITION LOCAL FRIENDS ltc_. My test class can’t see attribute _su01 of the CUT-class.īack to the Class-relevant Local Types tab, and add two more lines. That’s the idea, but there’s another syntax failure. And that returns the value that I set just before I invoke do_something_with_userid.Īt least. ![]() So it will be method exists of the test double that runs. When test_with_existence runs, _su01 in method do_something_with_userid will be bound already to the test double. Me->cut->do_something_with_userid( sy-uname ). Test_w_o_existence FOR TESTING RAISING cx_static_check, Test_with_existence FOR TESTING RAISING cx_static_check, I’ll put it in the setup method, as I probably don’t ever want to use the actual CL_SU01 during unit testing. Ok, now I’ve a test double, I can use it my unit test methods. This is what my ltd_su01 class looks likes (wrt to the method exists). If it gets really cumbersome, it might be an idea to put the test doubles within their own include – but I’ve found this complicates navigation and makes things less visible. I prefer to put my test doubles before my actual unit tests. I create class ltd_su01 in the Test Classes tab. This bit of code is finished, but before I can test it, I need a test double. Now lcl_su01 isn’t visible, so in the Class-relevant Local Types tab, I add CLASS lcl_su01 DEFINITION DEFERRED. The method exists of lcl_su01 has the same signature of as exists in CL_SU01, and it’s a simple pass-through call. In the CUT-class method where I need user information, I can do something like this (I’ve included the definition of the class attribute to make it clearer.: CLASS-DATA: But lif_su01 isn’t visible to the CUT-class, so in the Class-relevant Local Types tab, I add INTERFACE lif_su01 DEFERRED. These are written in the Local Types tab of the CUT.class.įirst, I create a class attribute in the private section of my CUT-class, which will be an instance of lif_su01. Initially, my local interface and class are empty, except lcl_su01 has an attribute which is a instance of CL_SU01,Īs I’m building my code (write test, test, write code, test, fix…) I come across (in the fix phase) a need to call a method of CL_SU01. I add that to the methods of lif_su01 and implement in lcl_su01, The method in the local classes calls the same method, which has the same signature, of my instance of CL_SU01. In my “code under test” class (from here referred to as my CUT-class), I create a local interface – lif_su01 with the same method definitions I need (and only those I need) from CL_SU01, and a local class. I’m working on 7.31 so I can’t use all the techniques you get on higher versions which make test doubles so much easier. ![]() It’s a nicely written bit of code, but with my tests, I don’t want to actually create or maintain any users. The first problem I’ve got is a class that wraps user maintenance (let’s call it CL_SU01). What I want to record is where I’ve met specific issues while developing the new version, and how I tackled them. I mean – who wouldn’t? For various reasons, I cannot change any existing dependent classes. ![]() Since I’m starting from scratch, I’m naturally using the Test Driven Development approach. This functionality has been modified in the past few years pretty extensively by a number of different programmers with different styles – although I wrote the initial version. I’ve been asked to rewrite a fairly important bit of functionality. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |