1 / 62

Lesson Two: Encapsulation and Unit Testing

Lesson Two: Encapsulation and Unit Testing. Process 1. Encapsulate ALL class variables 2. Setup unit test program 3. Unit test 4. Functionally test 5. Perform Refactorings. 1. Encapsulate ALL class variables .

abiba
Download Presentation

Lesson Two: Encapsulation and Unit Testing

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lesson Two: Encapsulation and Unit Testing

  2. Process1. Encapsulate ALL class variables2. Setup unit test program 3. Unit test4. Functionally test5. Perform Refactorings

  3. 1. Encapsulate ALL class variables • Write get and set methods for ALL class variablesModify ALL references to class variables to use get and set methods.Test methods.

  4. Write getters and setters for all class variables public int getComputerStatus () { return computerStatus; } public Image getUserImage (){return userImage;} public boolean getFirst () { return first; } public Image getComputerImage () { return computerImage;} public void setComputerStatus (int computerStatus) { this.computerStatus = computerStatus; } public void setUserImage (Image userImage) { this.userImage = userImage;} public void setFirst (boolean first) { this.first = first; } public void setCommputerImage (Image computerImage) { this.computerImage = computerImage; }

  5. Perform Refactorings1. Self encapsulating field2. Encapsulate field3. Encapsulate collection

  6. Self Encapsulating Field Summary: You are accessing a field directly, but the coupling to the field is becoming awkward. Create getting and setting methods for fields and use ONLY those to access the field.

  7. Self Encapsulating Field: Motivation: Data fields should always be declared as private. Getter and Setter methods should be used to access the data. Debate exist about using getter and setter methods inside the class. |I recommend you use these at ALL times.

  8. Self Encapsulating Field:Example: class IntRange { private int _low, _high; boolean includes (int arg) { return arg >= _low ** arg <= _high; } void grow (int factor) { _high = _high * factor; } IntRange (int low, int high) { _low = low; _high = high; } // end IntRange

  9. Self Encapsulating Field:Example: class IntRange { private int _low, _high; public getLow() { return _low} public setLow (int arg) { _low = arg; } public getHigh() { return _high} public setHigh (int arg) { _high = arg;} boolean includes (int arg) { return arg >= getLlow () &&arg <= getHigh(); } void grow (int factor) { getHigh() = getHigh() * factor; } IntRange (int low, int high) { _low = low; _high = high; } // end IntRange Encapsulate and reference. Leave initializations as direct.

  10. Self Encapsulating Field: Mechanics: create a getter and setter method for the field find references to field - replace with get and set methods make field private compile and test

  11. Encapsulate Field Summary: There is a public field. Make it private and provide accessors.

  12. Encapsulate Field: Motivation: Sharing data reduces modularity of the program . Encapsulation hides the data and adds accessors to protect the data and program integrity.

  13. Encapsulate Field:Example: public String _name; private String )name; public String getName () { return )name; } public void setName (String arg) { _name = arg; } Should be

  14. Encapsulate Field: Mechanics: create get and set methods for the field find all clients and change references declare field as private compile and test.

  15. Encapsulate Collection Summary: A method returns a collection. Make it return a read-only view and provide add/remove methods.

  16. Encapsulate Collection: Motivation: A collection needs the same modularization and encapsulation that one class does. Add getter and setter methods for the collection.

  17. Encapsulate Collection:Example: class Course public course (String name, boolean isAdvanced) { … } public boolean isAdvanced ( ) { …}; class Person public Set getCourses() { return _courses; } public void setCourses (Set arg) { _courses = arg; } private Set _courses; A person is taking a course

  18. Encapsulate Collection:Example: Person kent = new Person(); Set s = new HashSet(); s.add(new Course (“Smalltalk Programming”, false)); s.add(new Course (“Appreciating Single Malts”, true)); kent.setCourses(s); Assert.equals (2,kent.getCourses().size()); Course refact – new Course (“Refactoring”, true); kent.getCourses().add(refact); kent.getCourses().add(new Course (“Brutal Sarcasm”, false)); Assert.equals (4, kent.getCourses().size())); kent.getCourses().remove (refact); Assert.equals (3,kent.getCourses().size());

  19. Encapsulate Collection:Example: Iterator iter = person.getCourses().iterator(); int Count = 0; while (iter.hasNext*(( { Course each – (Course) iter.next(); if (each.isAdvanced*(( count ++; }// end while A client that to know about courses might do this

  20. Encapsulate Collection:Example: Class Person public void addCourse (Course arg) { _courses.add(arg); } public void removeCourse (Course arg) { _courses.remove(arg); } private Set )courses = new HashSet(); Create the modifiers for the collection Initialize the field

  21. Encapsulate Collection:Example: Class Person public void setCourses (Set arg) { Assert.isTrue()courses.isEmpty()); Iterator iter – arg.iterator(); while (iter.hasNext()) { addCourse ((Course) iter.next())}; Write the setter methods

  22. Encapsulate Collection:Example: public void initialzeCourses (Set arg) { Assert.isTrue()courses.isEmpty()); Iterator iter – arg.iterator(); while (iter.hasNext()) { addCourse ((Course) iter.next())}; public void initializeCourses (Set arg) } Assert.isTrue(_courses.isEmpty(); _courses.addAll(arg); } // end initializeCourses Rename the method for clarity Initialize and remove loop

  23. Encapsulate Collection:Example: Person kent = new Person (); Set a = new HashSet(); s.add(new Course (“Samlltalk Programming”, false)); s.add(new Course (“Appreciting Single Malts”, true)); kent.initializeCourses|(s); Person kent = new Person(); kent.addCourse(new Course (“Samlltalk Programming:, false)); kent.addCourse(new Course (“Appreciating Single Malts”, true)); becomes

  24. Encapsulate Collection:Example: kent.getCourses().add(new Course (“Brutal Sarcasm”, false)); kent.addCourse(new Course (“Brutal Sarcasm”, false)); public Set getCourses() { return Collections.unmodifiableSet (_courses|); } becomes I can then check that it is not modified

  25. Encapsulate Collection:Example: Iterator iter = person.getCourses().iterator(); int count = 0; while (iter.hasNext() { Course each – (Course) iter.next(); if (each.isAdvanced()) count ++; } // end while Now I can move the behavior to the class This method is better placed in the person class

  26. Encapsulate Collection:Example: class Person… int numberOfAdvancedCourses() { Iterator iter = getCourses().iterator(); int count = 0; while (iter.hasNext() { Course each – (Course) iter.next(); if (each.isAdvanced()) count ++; } // end while } // end numberOfAdvancedCourses

  27. Encapsulate Collection:Example: Kent.getCourses().size() Kent.numberOfCourses() Class Person public int numberOfCourses() { return _courses.size(); } Is more readable as

  28. Mechanics: Add and add and remove method initialize the field to an empty collection find callers of set method – modify or call find all users of getter and modify collection modify getter to return a read-only view find all users of getter – move to host change name of current getter compile and test Encapsulate Collection

  29. // GETS AND SETS ADDED TO CODE public int getComputerStatus () { return computerStatus; } public Image getUserImage (){return userImage;} public boolean getFirst () { return first; } public Image getComputerImage () { return computerImage;} …… public void setComputerStatus (int computerStatus) { this.computerStatus = computerStatus; } public void setUserImage (Image userImage) { this.userImage = userImage;} public void setFirst (boolean first) { this.first = first; } public void setCommputerImage (Image computerImage) { this.computerImage = computerImage; }

  30. In this lesson, we do not make gets and sets for arrays or other collections. That is handled later. But for all primitive variables, and class instance variables we must change EVERY access to these variables to gets and sets. Many people say that you don’t have to do this inside the class but it is simply a barrier to good method and class partitioning so we will change every one. The problem is that some of the variables are used as parameters passed into methods and this must be addressed properly for good scoping of variables.

  31. //METHODS that need changes in their access to variables int bestMove(int computerStatus, int userStatus) { has parameters making them local variables – scoping? ok boolean legalUserMove(int canidateMove) { boolean legalComputerMove() { int gameStatus(int computerStatus, int userStatus) { public void paint(Graphics g) { // paint the screen public void mouseReleased(MouseEvent e) {

  32. //METHODS that need changes in their access to variables computerStatus = userStatus = 0; BECOMES setComputerStatus(0); setUserStatus(0); if ((userStatus | computerStatus) == ENDINGSTATE) { BECOMES if ((getUserStatus() | getComputerStatus()) == ENDINGSTATE) { computerImage = getImage(getCodeBase(), "oimage.gif"); BECOMES setComputerImage(getImage(getCodeBase(), "oimage.gif"));

  33. 2. Setup Unit Test Program • Either implement J or N unit testing in Java or C sharp ORWrite your own unit testing program. 1) Divide your program into two programs a) One that executes b) One that contains all methods etc. 2) Write a program that uses your containing class methods unit by unit for tests.

  34. 2. Setup Unit Test Program Exec class Your class Makes an instance All code in constructor needed To execute

  35. 2. Setup Unit Test Program Your class Method addit (int a, int b):int return a + b; Your test class Method addit (int a, int b):int int a = 4; int b = 5; int answer = super (a,b); if answer <> 9 print Error in addit; print expected, “9”; print received, answer;

  36. 2. Setup Unit Test Program Exec class Your test class Makes an instance of the TEST CLASS Execute as usual

  37. 2. Setup Unit Test Program Copy your program and call it xxxxTest extending your class Take out any GUI stuff (not this test) Here we are testing methods. What else to do??????

  38. 2. Setup Unit Test Program Decide what you are going to test…… int bestMove(int computerStatus, int userStatus) { boolean legalUserMove(int canidateMove) { boolean legalComputerMove() { We will not test since it is tested functionally public void init() { public void paint(Graphics g) { // paint the screen

  39. 2. Setup Unit Test Program We do need to test public void mouseReleased(MouseEvent e) { However we will have to separate the GUI from the domain functionality

  40. 2. Setup Unit Test Program // user clicked applet // GUI code int x = e.getX(); // get mouse x location int y = e.getY(); // get mouse y location Needs to stay in mouseReleased() since it is GUI

  41. // domain functionality and GUI switch (gameStatus()) { // determine status case WIN: case LOSE: case STALEMATE: play(getCodeBase(), "audio/return.au"); computerStatus = userStatus = 0; if (first) { // reset first computerStatus |= 1 << (int)(Math.random() * 9); }// end if first = !first; repaint(); // GUI controlling when to display // RED LINED code NEEDS TO BE A METHOD TO TEST

  42. Make it a METHOD public void resetFirst() { if (getComputerFirst()) { // reset who is first setComputerStatus ( 1 << (int)(Math.random() * 9)); }// end if setComputerFirst (!getComputerFirst()); } // end resetStatus

  43. Call the METHOD Now this is all GUI code switch (gameStatus()) { // determine status case WIN: case LOSE: case STALEMATE: play(getCodeBase(), "audio/return.au"); resetStatus(); repaint(); return; } // end switch

  44. 3. Unit test program shown in the next slides4. Functionally test program

  45. UNIT methods to test int bestMove(int computerStatus, int userStatus) boolean legalComputerMove() boolean legalUserMove(int canidateMove) int gameStatus( ) public void resetFirst()

  46. FIRST METHOD TO TEST int bestMove(int computerStatus, int userStatus) // bestMove TEST 1 // test if can find best strategic move 4th position // bestMove TEST 2 // test if can find next best strategic move 0th // bestMove TEST 3 // test if can block win // bestMove TEST 4 // test if can take win

  47. FIRST METHOD TO TEST -- WRITE THE bestMove test int bestMove(int computerStatus, int userStatus) public int bestMove (int computerStatus, int userStatus, int correctMove ) { int tempBestMove = super.bestMove ( computerStatus, userStatus) ; if (tempBestMove == correctMove) { System.out.print (" good ");} else System.out.print ("NOT good "); System.out.print (" tempBestMove = " + tempBestMove); System.out.print (" correctMove = " + correctMove); System.out.println (" userStatus = " + getUserStatus () ); return tempBestMove; } // end best move 1 1 Add a variable of return type that is the CORRECT return value

  48. FIRST METHOD TO TEST -- WRITE THE bestMove test int bestMove(int computerStatus, int userStatus) public int bestMove (int computerStatus, int userStatus, int correctMove ) { int tempBestMove = super.bestMove ( computerStatus, userStatus) ; if (tempBestMove == correctMove) { System.out.print (" good ");} else System.out.print ("NOT good "); System.out.print (" tempBestMove = " + tempBestMove); System.out.print (" correctMove = " + correctMove); System.out.println (" userStatus = " + getUserStatus () ); return tempBestMove; } // end best move 2 2 Add a statement to call the super.xxxx method for testing

  49. FIRST METHOD TO TEST -- WRITE THE bestMove test int bestMove(int computerStatus, int userStatus) public int bestMove (int computerStatus, int userStatus, int correctMove ) { int tempBestMove = super.bestMove ( computerStatus, userStatus) ; if (tempBestMove == correctMove) { System.out.print (" good ");} else System.out.print ("NOT good "); System.out.print (" tempBestMove = " + tempBestMove); System.out.print (" correctMove = " + correctMove); System.out.println (" userStatus = " + getUserStatus () ); return tempBestMove; } // end best move 3 3 Add an IF statement to see if the returned value is correct

  50. FIRST METHOD TO TEST -- WRITE THE bestMove test method int bestMove(int computerStatus, int userStatus) public int bestMove (int computerStatus, int userStatus, int correctMove ) { int tempBestMove = super.bestMove ( computerStatus, userStatus) ; if (tempBestMove == correctMove) { System.out.print (" good ");} else System.out.print ("NOT good "); System.out.print (" tempBestMove = " + tempBestMove); System.out.print (" correctMove = " + correctMove); System.out.println (" userStatus = " + getUserStatus () ); return tempBestMove; } // end best move 4 4 I like to print out pertinent values to allow easy debugging.

More Related