1 00:00:02,391 --> 00:00:06,929 Hi, my name is sandro mancuso 2 00:00:06,929 --> 00:00:09,533 in this screen cast 3 00:00:09,533 --> 00:00:15,865 we're gonna take a piece of existing code without test 4 00:00:15,865 --> 00:00:18,125 we're gonna write tests for it first 5 00:00:18,125 --> 00:00:20,568 and when it is 100% covered 6 00:00:20,568 --> 00:00:23,567 then we're gonna refactor it to make it better 7 00:00:23,567 --> 00:00:25,594 so, the business requirements are 8 00:00:25,594 --> 00:00:28,607 imagine a social networking website for travellers 9 00:00:28,607 --> 00:00:33,597 so, you need to be logged in to see any type of content 10 00:00:33,597 --> 00:00:35,550 and as soon as you logged in 11 00:00:35,550 --> 00:00:37,462 if you want to see someone else's trips 12 00:00:37,462 --> 00:00:39,887 you need to be friends with this person 13 00:00:39,887 --> 00:00:42,125 it's kind of like your facebook stuff 14 00:00:42,125 --> 00:00:45,553 so, if you're friends with someone you can see this person's trip 15 00:00:45,553 --> 00:00:47,678 otherwise, you can't 16 00:00:49,268 --> 00:00:51,169 so, but there are a few rules 17 00:00:51,169 --> 00:00:56,129 we can not touch production code if it's not covered by tests 18 00:00:57,219 --> 00:01:03,179 so, as we know, sometimes we should write test for existing code 19 00:01:03,179 --> 00:01:04,980 we need to change the existing code 20 00:01:04,980 --> 00:01:10,258 so the only exception to this rule is that you can use automatic refactoring 21 00:01:10,258 --> 00:01:14,713 by our IDE, never type into the file 22 00:01:16,063 --> 00:01:19,632 so, one approach that we gonna take is 23 00:01:19,632 --> 00:01:24,114 imagine that this is how your code looks like 24 00:01:24,114 --> 00:01:29,233 instead of trying to go to write test from the deepest branch 25 00:01:29,503 --> 00:01:34,435 we're gonna choose the shortest branch of the code and write a test for that 26 00:01:35,148 --> 00:01:39,569 and then we look at the second shortest branch 27 00:01:39,569 --> 00:01:41,472 and then write a test for that 28 00:01:41,472 --> 00:01:45,420 cause that gives us the ability to test by test 29 00:01:45,527 --> 00:01:47,770 understand what our code does 30 00:01:47,882 --> 00:01:54,287 and also we build up our test suite so we can get to the deepest branch 31 00:01:54,287 --> 00:01:58,375 if we start to write a test according to the deepest branch 32 00:01:58,375 --> 00:02:00,209 or trying to test the deepest branch 33 00:02:00,209 --> 00:02:06,100 normally we need to create a massive setup to get there 34 00:02:06,933 --> 00:02:09,392 so, we need to understand entire code base 35 00:02:09,392 --> 00:02:13,196 so we prefer to do from the shortest branch to the deepest 36 00:02:13,196 --> 00:02:15,263 let's see some code 37 00:02:15,263 --> 00:02:20,094 so this is the trip service class 38 00:02:20,774 --> 00:02:23,824 this is a server side class 39 00:02:24,564 --> 00:02:27,059 and basically what it does is 40 00:02:27,059 --> 00:02:28,998 it has a get trips by user 41 00:02:28,998 --> 00:02:31,167 receive a user in there 42 00:02:31,167 --> 00:02:35,983 so it checks the user session 43 00:02:35,983 --> 00:02:38,130 gets the user that is logged in 44 00:02:39,200 --> 00:02:44,795 then if the user is not logged in it throws an exception 45 00:02:44,795 --> 00:02:50,728 if the user is logged in then 46 00:02:50,728 --> 00:02:57,138 check if the logged in user is friends with the user passed as parameter 47 00:02:57,138 --> 00:02:59,859 and if they're friends then I can retrieve 48 00:02:59,859 --> 00:03:03,879 the list of trips for the user passed through parameter 49 00:03:03,879 --> 00:03:07,748 so a bit confusing for now but what I'm gonna do 50 00:03:07,748 --> 00:03:11,287 let's start writing test for it 51 00:03:11,287 --> 00:03:14,534 may I just split the screen 52 00:03:14,534 --> 00:03:17,589 that's normally how I prefer to code 53 00:03:17,589 --> 00:03:19,725 I normally split my screen into two 54 00:03:19,725 --> 00:03:21,814 I have my production code in one side 55 00:03:21,814 --> 00:03:23,304 my test on the other side 56 00:03:23,304 --> 00:03:27,091 then I don't need to keep switching from one to another 57 00:03:27,091 --> 00:03:31,037 so that's my favorite way of coding 58 00:03:31,037 --> 00:03:33,919 so, the first thing that we do 59 00:03:33,919 --> 00:03:35,848 we just look for the shortest branch 60 00:03:35,848 --> 00:03:37,068 we can ignore entire thing 61 00:03:37,068 --> 00:03:39,198 I don't care what this does for now 62 00:03:39,388 --> 00:03:41,506 for me, when I'm working with legacy code 63 00:03:41,506 --> 00:03:42,990 the first thing that I do is 64 00:03:43,097 --> 00:03:44,613 if I want to see what this code does 65 00:03:44,613 --> 00:03:46,151 I look for the shortest branch 66 00:03:46,151 --> 00:03:49,343 if the logged user is different from null 67 00:03:49,378 --> 00:03:51,082 then it throws an exception 68 00:03:51,082 --> 00:03:53,775 so if it is not logged in throws an exception 69 00:03:53,775 --> 00:03:56,833 so let's write a test to see if that's true 70 00:03:57,473 --> 00:04:12,537 so, should throw an exception when user is not logged in 71 00:04:13,177 --> 00:04:16,501 let's put the exception here 72 00:04:16,539 --> 00:04:22,550 expect it, user not logged in exception 73 00:04:24,400 --> 00:04:27,414 so let's create the trip service 74 00:04:33,453 --> 00:04:34,845 import that 75 00:04:35,239 --> 00:04:37,163 now what we should do 76 00:04:37,163 --> 00:04:41,644 trip service dot 77 00:04:42,276 --> 00:04:44,346 get trips by user 78 00:04:44,346 --> 00:04:46,620 pass as null here for now 79 00:04:50,289 --> 00:04:52,189 I'm using Infinitest 80 00:04:52,199 --> 00:04:55,975 so this red bar here basically show 81 00:04:55,975 --> 00:04:59,208 everytime that I save my test or my production code 82 00:04:59,208 --> 00:05:00,922 it runs my test for me 83 00:05:00,922 --> 00:05:02,899 so I don't need to keep trying with my hands 84 00:05:02,899 --> 00:05:05,419 this should be in theory 85 00:05:05,754 --> 00:05:06,536 green 86 00:05:06,746 --> 00:05:09,624 but something is happening 87 00:05:09,624 --> 00:05:19,824 so if I run junit by hand 88 00:05:19,824 --> 00:05:22,573 basically what's happening is 89 00:05:22,573 --> 00:05:27,696 this should throw user not loggedn in exception 90 00:05:27,696 --> 00:05:30,636 it's expecting user not logged in exception 91 00:05:30,636 --> 00:05:34,894 but it's throwing a dependent a class during blah blah 92 00:05:34,928 --> 00:05:37,669 so basically what's happening is 93 00:05:41,119 --> 00:05:46,689 when this line here is executed 94 00:05:49,109 --> 00:05:55,189 so when I say user session, get instance, get logged user 95 00:05:56,189 --> 00:05:57,840 the user session 96 00:05:57,840 --> 00:06:00,835 I did that on purpose of course 97 00:06:00,835 --> 00:06:02,613 throws an exception 98 00:06:03,303 --> 00:06:06,217 basically because in a unit test 99 00:06:06,217 --> 00:06:10,747 we shouldn't be invoking other classes 100 00:06:11,311 --> 00:06:14,654 because this may have the dependency of http session 101 00:06:14,654 --> 00:06:18,027 it could go to the database to retrieve stuff 102 00:06:18,027 --> 00:06:19,848 so we don't want that 103 00:06:20,556 --> 00:06:22,978 so we need to break these dependencies 104 00:06:24,238 --> 00:06:26,113 the problem that we have is 105 00:06:26,113 --> 00:06:27,732 this is a singleton 106 00:06:27,732 --> 00:06:32,605 and I cannot mock it right now 107 00:06:32,605 --> 00:06:37,844 so I can't inject it, I can't type inside this trip service 108 00:06:38,943 --> 00:06:41,900 but I need to find a way to get rid of it 109 00:06:41,900 --> 00:06:44,142 I need to find a way to mock that 110 00:06:44,142 --> 00:06:48,323 so the only things that I can do, as I said before 111 00:06:48,323 --> 00:06:50,679 is I need to use automated refactoring 112 00:06:50,679 --> 00:06:51,693 but I cannot not type 113 00:06:51,693 --> 00:06:53,625 so here what I'm gonna do 114 00:06:53,625 --> 00:06:55,547 I'm gonna create a seam 115 00:06:55,547 --> 00:06:59,959 so seam is the division of where the two classes 116 00:06:59,959 --> 00:07:02,741 the seam is where two classes meet 117 00:07:02,741 --> 00:07:04,802 the trip service and the user session 118 00:07:04,802 --> 00:07:06,466 so I'm gonna create this seam 119 00:07:06,466 --> 00:07:09,398 so what I'm gonna do, I'm gonna create a method 120 00:07:09,989 --> 00:07:14,962 saying get logged in user 121 00:07:16,511 --> 00:07:18,283 and I will make that protected 122 00:07:19,153 --> 00:07:27,023 so I just isolated the bit that goes to the other class 123 00:07:27,543 --> 00:07:29,474 and that's my seam 124 00:07:30,007 --> 00:07:33,732 so now what I can do as an intermediary step 125 00:07:33,732 --> 00:07:44,853 I can create a private class, testable trip service 126 00:07:44,853 --> 00:07:49,386 that extends the trip service 127 00:07:52,186 --> 00:07:54,431 so what I do 128 00:07:54,471 --> 00:08:03,556 I override the get logged in user 129 00:08:03,827 --> 00:08:07,330 and I make it return null 130 00:08:10,577 --> 00:08:17,812 and in my test, I replace the trip service by testable trip service 131 00:08:23,662 --> 00:08:28,534 and so if I try to run that 132 00:08:28,569 --> 00:08:32,208 now I have it green as you can see here 133 00:08:32,208 --> 00:08:35,443 my infinitest somtimes goes crazy 134 00:08:35,535 --> 00:08:39,021 sometimes I can trust, sometimes I cannot trust 135 00:08:39,021 --> 00:08:44,923 in this case it was red but my tests are green now 136 00:08:44,956 --> 00:08:49,496 so in theory I should be happy with that 137 00:08:49,823 --> 00:08:53,473 just to confirm, so my test is green 138 00:08:54,206 --> 00:08:58,610 and if I run my code coverage 139 00:08:59,530 --> 00:09:05,990 so I make sure that I'm testing the shortest branch 140 00:09:05,990 --> 00:09:08,614 so that's another good tip 141 00:09:08,614 --> 00:09:11,220 cause every time that I work with legacy code 142 00:09:11,220 --> 00:09:13,143 I always use code coverage 143 00:09:13,143 --> 00:09:15,104 so lots people thing code coverage ... 144 00:09:15,104 --> 00:09:16,954 ah... it's test coverage 145 00:09:16,954 --> 00:09:18,726 I don't care about the percentage 146 00:09:18,726 --> 00:09:22,710 the important thing for me here is, when I'm working with legacies 147 00:09:22,710 --> 00:09:27,918 is my test covering the branch that I thought it would cover 148 00:09:27,918 --> 00:09:30,897 because this avoid the false positives and negatives 149 00:09:30,897 --> 00:09:32,973 so I know exactly what I'm doing now 150 00:09:33,003 --> 00:09:35,125 so that's cool 151 00:09:35,125 --> 00:09:41,664 so let's remove that the code ceverage 152 00:09:47,294 --> 00:09:50,287 however this test is far from being good 153 00:09:50,287 --> 00:09:52,593 because look at this 154 00:09:52,593 --> 00:09:56,002 should throw an exception when user is not logged in 155 00:09:57,452 --> 00:10:01,813 this test is all about the user not being logged in 156 00:10:02,873 --> 00:10:05,067 but where does it say it in here 157 00:10:05,137 --> 00:10:08,358 here we created the testable trip service 158 00:10:08,358 --> 00:10:11,229 we invoke a method, pass null, throws an exception 159 00:10:11,229 --> 00:10:14,606 but where's the user not logged in? 160 00:10:16,785 --> 00:10:18,635 it's here, it's hidden 161 00:10:18,825 --> 00:10:21,353 so we need to fix that 162 00:10:21,353 --> 00:10:23,593 we need to introduce the concept 163 00:10:23,593 --> 00:10:26,785 oh by the way, the reason that I have this weird notation in here 164 00:10:26,785 --> 00:10:30,088 it's kind of weird for java people 165 00:10:30,088 --> 00:10:32,264 but normally the Ruby they use this convention 166 00:10:32,264 --> 00:10:34,191 because I can just collapse the method 167 00:10:34,191 --> 00:10:38,552 and then I have the specification of my class 168 00:10:38,552 --> 00:10:40,097 and normally I read like 169 00:10:40,097 --> 00:10:44,711 trip service should do something 170 00:10:44,711 --> 00:10:49,632 so that's how I normally prefer to create my test 171 00:10:50,352 --> 00:10:55,961 so this is all about the logged in user that is not there anywhere 172 00:10:55,961 --> 00:10:57,502 so I'm gonna create it 173 00:10:58,981 --> 00:11:06,355 logged in user is null 174 00:11:07,815 --> 00:11:09,859 so now I'm gonna create this guy 175 00:11:09,859 --> 00:11:15,649 create field user logged in user 176 00:11:18,209 --> 00:11:23,326 and I'm gonna say logged in user 177 00:11:24,142 --> 00:11:28,647 so now it is little bit better because I introduced the concept that I was talking about 178 00:11:31,599 --> 00:11:35,383 I don't like the nulls 179 00:11:35,383 --> 00:11:39,426 cause null doesn't mean much in this case 180 00:11:39,426 --> 00:11:51,008 so let's say logged in user is not logged in 181 00:11:51,008 --> 00:11:55,112 or in fact in a web application 182 00:11:56,613 --> 00:12:01,137 the opposite of logged in user is normally a guest 183 00:12:01,137 --> 00:12:06,422 so here we take the opportunity start using the concepts that 184 00:12:06,422 --> 00:12:10,642 you probably gonna speak the behavior to business people 185 00:12:10,642 --> 00:12:14,401 right, so it started to use your domain language 186 00:12:15,379 --> 00:12:22,429 in here, I have the user that should be friends with or not 187 00:12:22,549 --> 00:12:25,927 in this case, I prefer to make it explicit that is 188 00:12:28,257 --> 00:12:30,602 unused user 189 00:12:39,757 --> 00:12:45,394 so now, see if I can 190 00:12:45,713 --> 00:12:52,950 I'm just trying to see if I can make my Infinitest be happy 191 00:12:53,863 --> 00:12:54,802 but it's not 192 00:12:54,802 --> 00:12:58,157 so I won't be trusting my Infinitest unfortunately 193 00:13:02,375 --> 00:13:04,714 so I much happier with my test now 194 00:13:04,714 --> 00:13:08,320 and by the way my Infinitest is working again 195 00:13:09,030 --> 00:13:11,755 so now my test reflex what I was talking about 196 00:13:11,755 --> 00:13:14,523 so should throw an exception when user is not logged in 197 00:13:14,523 --> 00:13:16,913 so the logged in user is a guest 198 00:13:16,913 --> 00:13:18,760 and then throws an exception 199 00:13:18,760 --> 00:13:19,791 so awesome 200 00:13:19,791 --> 00:13:21,524 so what we can do right now is 201 00:13:21,524 --> 00:13:23,419 rerun the code coverage 202 00:13:30,309 --> 00:13:32,452 I just want to run the junit first 203 00:13:32,452 --> 00:13:34,001 just to make it sure 204 00:13:34,001 --> 00:13:34,716 cool 205 00:13:34,770 --> 00:13:37,307 now I can run my code coverage 206 00:13:43,247 --> 00:13:45,433 so now what I do is 207 00:13:45,462 --> 00:13:46,702 according to my code coverage 208 00:13:46,702 --> 00:13:50,701 I can easily see what is the second shortest branch 209 00:13:51,701 --> 00:13:56,261 so basically, now is this for loop in here 210 00:13:57,401 --> 00:14:00,243 and then I say if it's friend 211 00:14:00,243 --> 00:14:02,411 so this is the deepest 212 00:14:02,411 --> 00:14:05,574 cause to get to here this flag needs to be true 213 00:14:05,631 --> 00:14:10,190 so basically what I need now is when the user is logged in 214 00:14:10,190 --> 00:14:14,368 but he's not friends with the user passed as parameter 215 00:14:15,158 --> 00:14:19,708 so we're gonna write the test for that 216 00:14:19,708 --> 00:14:25,540 so let's keep the code coverage on 217 00:14:27,840 --> 00:14:31,701 so let's say 218 00:14:34,481 --> 00:14:48,450 should not return any trips when users are not friends, right? 219 00:14:48,450 --> 00:14:54,445 so I'm gonna borrow these guys here for seconds 220 00:14:57,215 --> 00:15:00,080 so now I need a logged in user 221 00:15:00,080 --> 00:15:03,914 so I say, a registered user 222 00:15:05,062 --> 00:15:06,632 let's create this guy 223 00:15:14,092 --> 00:15:23,964 and here what I would need is a list trip trips 224 00:15:24,174 --> 00:15:29,728 let's call it friend trips 225 00:15:30,458 --> 00:15:32,110 so import all that 226 00:15:42,970 --> 00:15:44,695 so basically what I need now 227 00:15:44,695 --> 00:15:45,936 I need a proper user 228 00:15:45,936 --> 00:15:48,716 I can't have a user in here 229 00:15:49,076 --> 00:15:51,316 so I'll call it a 230 00:15:51,726 --> 00:15:55,126 let's call it friend 231 00:15:56,096 --> 00:16:00,197 so I need a user that is friend 232 00:16:04,062 --> 00:16:11,363 so add friend, another user 233 00:16:13,663 --> 00:16:18,701 friend, let's say add trip to brazil 234 00:16:22,380 --> 00:16:25,177 so let's create these guys 235 00:16:41,417 --> 00:16:44,548 ans so now I have a friend 236 00:16:44,928 --> 00:16:48,566 that is friend with another user that has a trip to brazil 237 00:16:49,046 --> 00:16:52,619 I have a logged in user that is a valid user 238 00:16:53,409 --> 00:16:55,868 but they're not friends 239 00:16:55,868 --> 00:17:01,960 so I need to assert that 240 00:17:03,655 --> 00:17:08,524 friend trip dot size is zero 241 00:17:10,904 --> 00:17:13,694 right, I could have said 242 00:17:13,694 --> 00:17:16,294 assert that is empty doesn't matter 243 00:17:16,294 --> 00:17:20,236 so my Infinitest that apparently is working 244 00:17:20,320 --> 00:17:24,997 just confirm running the JUnit command 245 00:17:25,137 --> 00:17:27,421 so it saying that it is green 246 00:17:27,421 --> 00:17:29,726 that happens quite often in legacy code 247 00:17:29,726 --> 00:17:30,975 cause the code is already there 248 00:17:30,975 --> 00:17:33,396 you just making sure that you understand what code does 249 00:17:33,396 --> 00:17:34,624 so that's quite common 250 00:17:34,624 --> 00:17:37,479 I'm just run the code coverage 251 00:17:37,508 --> 00:17:40,781 so running the code coverage now we progressed little bit 252 00:17:40,781 --> 00:17:44,556 so as you can see my new test now moved forward 253 00:17:44,556 --> 00:17:46,165 so went for the shortest branch 254 00:17:46,165 --> 00:17:49,279 where the user was logged in 255 00:17:49,279 --> 00:17:50,949 but they were not friends 256 00:17:52,319 --> 00:17:56,641 so it was returning always false and then that it 257 00:17:57,202 --> 00:17:59,308 so we're not done yet 258 00:17:59,308 --> 00:18:02,308 because now we need to do some refactoring here 259 00:18:02,308 --> 00:18:04,474 there is some duplication 260 00:18:04,474 --> 00:18:06,296 so let's get rid of it 261 00:18:07,086 --> 00:18:10,784 so let's put a before method 262 00:18:12,558 --> 00:18:15,420 let's transform this guy 263 00:18:15,420 --> 00:18:18,613 local variable into field 264 00:18:18,642 --> 00:18:20,687 it's great 265 00:18:20,687 --> 00:18:22,238 it's awsome 266 00:18:24,568 --> 00:18:26,605 now we can move this guy up 267 00:18:35,795 --> 00:18:37,168 right 268 00:18:38,288 --> 00:18:44,047 so now I can go to the deepest branch 269 00:18:44,067 --> 00:18:45,674 so now what I need is 270 00:18:45,674 --> 00:18:51,574 when the logged in user is friends with the user passed as parameter 271 00:18:52,944 --> 00:18:56,169 then I need the trips, return the trips 272 00:18:59,855 --> 00:19:07,710 should return friend trips when users are friends 273 00:19:08,735 --> 00:19:11,072 right? so that's the one we testing 274 00:19:11,072 --> 00:19:13,591 so I'm gonna borrow this again 275 00:19:22,717 --> 00:19:24,967 so you shouldn't do copy and pate 276 00:19:24,967 --> 00:19:26,967 I don't do copy and paste 277 00:19:26,997 --> 00:19:29,316 what you saw was an illusion 278 00:19:29,316 --> 00:19:33,275 so I never, never ever do copy and paste 279 00:19:34,435 --> 00:19:37,800 so in this case here what I want you to do now is 280 00:19:38,660 --> 00:19:45,833 friend, add friend with logged in user 281 00:19:46,806 --> 00:19:49,182 let's add another trip 282 00:20:03,431 --> 00:20:08,223 so now of course that I expect my Infinitest are red saying with this 283 00:20:08,223 --> 00:20:11,517 red, of course I expect this should be true 284 00:20:11,517 --> 00:20:13,910 because now the users are friends 285 00:20:13,910 --> 00:20:14,777 and if I save 286 00:20:14,777 --> 00:20:18,513 it still saying that it's red 287 00:20:18,513 --> 00:20:21,700 so let's run junit by hand 288 00:20:21,700 --> 00:20:25,280 oops, I keep getting the shortcuts wrong 289 00:20:25,280 --> 00:20:27,619 because I kept using windows 290 00:20:27,619 --> 00:20:32,589 my mac and intellij keep getting (???) 291 00:20:32,589 --> 00:20:37,128 so what it's saying is, because now what's happening 292 00:20:37,908 --> 00:20:39,367 just restore this screen 293 00:20:40,268 --> 00:20:41,816 what's happening is 294 00:20:41,816 --> 00:20:47,416 the code is now getting here in the trip dao 295 00:20:47,416 --> 00:20:49,390 that is a statical 296 00:20:49,550 --> 00:20:53,211 and as soon as the code execute this guy 297 00:20:53,211 --> 00:20:55,029 then there's an exception being thrown 298 00:20:55,029 --> 00:20:56,735 now I give the same thing 299 00:20:56,735 --> 00:20:59,613 so this is just to prove the point that 300 00:20:59,613 --> 00:21:01,083 just to make a point 301 00:21:01,083 --> 00:21:06,523 that we shouldn't ever be calling or execute another class in a unit test 302 00:21:06,523 --> 00:21:13,061 because this, in the real world, would be going to the database and fetching data blah blah blah 303 00:21:12,721 --> 00:21:17,158 the test for my trip service shouldn't care about that 304 00:21:17,158 --> 00:21:21,533 so we need to do exactly the same thing 305 00:21:21,533 --> 00:21:25,171 that we've done for user session 306 00:21:25,171 --> 00:21:29,624 so you can break the hard wired dependencies 307 00:21:29,624 --> 00:21:32,980 like singleton and staticals 308 00:21:32,980 --> 00:21:36,949 or objects being created inside method is exactly the same 309 00:21:36,949 --> 00:21:39,167 so basically what we do 310 00:21:39,977 --> 00:21:41,583 create a method 311 00:21:42,493 --> 00:21:48,772 let's say trips by user 312 00:21:48,772 --> 00:21:51,293 that is also protected 313 00:21:51,293 --> 00:21:56,300 and then we go back to our tests 314 00:22:02,090 --> 00:22:04,414 we'll do the same thing 315 00:22:17,108 --> 00:22:19,844 so basically what we'll do 316 00:22:20,141 --> 00:22:22,319 we will just return 317 00:22:22,319 --> 00:22:23,668 so we will receive the user 318 00:22:23,668 --> 00:22:26,775 the user in our test that has two trips 319 00:22:29,275 --> 00:22:32,476 so basically we just return that 320 00:22:32,476 --> 00:22:35,154 the user dot trips 321 00:22:36,454 --> 00:22:39,076 so as soon as do that my test is green 322 00:22:40,046 --> 00:22:43,949 so if I run my code coverage 323 00:22:43,949 --> 00:22:45,098 awesome 324 00:22:45,098 --> 00:22:51,066 cause now I have all my existing code base 325 00:22:51,066 --> 00:22:53,736 tested to almost 100% 326 00:22:53,736 --> 00:22:59,963 of course that you might say that I created are not test because I overriding them 327 00:22:59,963 --> 00:23:02,403 but that's alright because that's just my seam 328 00:23:02,403 --> 00:23:04,881 that's a very thin layer to delegate 329 00:23:04,881 --> 00:23:07,448 and that's intermediatary stage anyway 330 00:23:07,448 --> 00:23:11,678 so now few clean ups that we can do 331 00:23:11,678 --> 00:23:13,373 normally what I do is 332 00:23:13,373 --> 00:23:19,127 because this guy is here and is here 333 00:23:19,127 --> 00:23:24,999 and the only situation that I don't want it should be like that is this one 334 00:23:24,999 --> 00:23:26,461 so I leave this one 335 00:23:26,461 --> 00:23:28,368 and I just move this one out 336 00:23:29,598 --> 00:23:31,708 because then it is common to all other tests 337 00:23:31,708 --> 00:23:37,277 all other tests that I want the logged in user should be a valid one 338 00:23:37,307 --> 00:23:40,045 so once I do that 339 00:23:40,088 --> 00:23:41,879 if I save 340 00:23:41,879 --> 00:23:44,332 then if I just make it sure 341 00:23:44,332 --> 00:23:46,438 so all my tests are green 342 00:23:46,438 --> 00:23:47,531 and that's great 343 00:23:47,531 --> 00:23:52,048 so for the first part, it's great we're done 344 00:23:52,048 --> 00:23:56,470 now our code is tested and we're free to start refactoring 345 00:23:57,450 --> 00:24:02,487 so now that we're in a very good point to commit 346 00:24:02,487 --> 00:24:06,112 so git status 347 00:24:06,112 --> 00:24:08,437 git commit 348 00:24:08,437 --> 00:24:17,763 unit tests for trip service 349 00:24:17,763 --> 00:24:19,614 cool, awesome 350 00:24:23,664 --> 00:24:26,109 look at this test, the problem is 351 00:24:26,109 --> 00:24:29,593 legacy code is that quite often you need 352 00:24:29,593 --> 00:24:32,426 this is of course very simple one 353 00:24:33,216 --> 00:24:39,395 but imagine like a same method with hundreds of line 354 00:24:39,395 --> 00:24:42,114 and here we're just talking about one object being created 355 00:24:42,114 --> 00:24:43,428 to pass in as parameter 356 00:24:43,428 --> 00:24:48,044 but quite often what we do is we need to create this massive object graph 357 00:24:48,044 --> 00:24:50,060 to pass in as parameter 358 00:24:50,060 --> 00:24:53,022 so we can reach all the branches and stuff 359 00:24:53,022 --> 00:24:55,161 so we can start cleaning that up 360 00:24:55,161 --> 00:24:58,112 cause I don't like all these duplication in here and here 361 00:24:58,112 --> 00:25:01,888 so the way that I would love to see it 362 00:25:01,888 --> 00:25:03,713 is using a builder 363 00:25:03,713 --> 00:25:09,018 so basically what I loved to see is something like that 364 00:25:09,018 --> 00:25:11,672 user friend 365 00:25:12,112 --> 00:25:18,756 kind of like a friend or a user 366 00:25:23,506 --> 00:25:35,245 friends with another user and logged in user 367 00:25:35,915 --> 00:25:45,607 with trips to brazil and to london 368 00:25:46,757 --> 00:25:49,860 so that's the sort of stuff that I would like to see 369 00:25:50,470 --> 00:25:51,836 I think I read far better 370 00:25:51,836 --> 00:25:54,757 so let's try to see if we can make that happen 371 00:25:55,127 --> 00:25:57,716 so let's put a build method in here 372 00:25:58,086 --> 00:26:00,337 let's use the builder pattern for that 373 00:26:01,593 --> 00:26:05,397 let's say user builder 374 00:26:06,667 --> 00:26:11,958 so that would be what I want to see 375 00:26:11,958 --> 00:26:15,655 so I will gonna comment this out a little bit 376 00:26:16,815 --> 00:26:24,640 so I'll say, public, static 377 00:26:25,439 --> 00:26:27,976 class, user builder 378 00:26:30,876 --> 00:26:34,195 let's start creating this method in there 379 00:26:47,525 --> 00:26:49,961 the way that you can chain methods 380 00:26:49,961 --> 00:26:52,980 you'll just keep returning the same object 381 00:26:52,980 --> 00:26:55,186 and then you can chain all the methods 382 00:26:55,186 --> 00:26:57,379 so let's create the use builder 383 00:27:00,659 --> 00:27:04,965 so now we just create the next method 384 00:27:07,535 --> 00:27:09,562 keep returning the user builder 385 00:27:09,752 --> 00:27:15,449 so here we're passing two users 386 00:27:17,039 --> 00:27:21,738 as I always said, there are just three numbers in programming 387 00:27:21,738 --> 00:27:24,445 there is 0, there is 1 and there is many 388 00:27:24,445 --> 00:27:26,724 there's nothing more than that 389 00:27:26,788 --> 00:27:29,590 so let's make it many 390 00:27:31,270 --> 00:27:33,300 so let's use variable arguments 391 00:27:33,300 --> 00:27:36,803 cause that I can pass many users as I want 392 00:27:38,113 --> 00:27:41,321 so let's put friends 393 00:27:43,211 --> 00:27:47,773 let's say these friends equals friends 394 00:27:48,043 --> 00:27:50,624 let's keep returning same objects 395 00:27:50,624 --> 00:27:52,887 let's create this guy 396 00:27:53,011 --> 00:27:57,611 should never leave arrays uninitialized 397 00:27:57,611 --> 00:28:01,089 so new user 398 00:28:05,399 --> 00:28:07,862 avoid some null pointer exception 399 00:28:08,662 --> 00:28:16,280 so great, let's go for our second method 400 00:28:16,361 --> 00:28:18,817 so user builder 401 00:28:18,817 --> 00:28:21,536 let's do the same thing 402 00:28:21,536 --> 00:28:28,132 because then we're free to use our method to pass as many trips as we want 403 00:28:37,012 --> 00:28:39,210 let's return trips 404 00:28:39,210 --> 00:28:41,015 let's create trips 405 00:28:41,015 --> 00:28:44,888 normally what I do 406 00:28:44,888 --> 00:28:48,704 I write the way I want to read it 407 00:28:48,836 --> 00:28:52,123 and then I start creating all the code from there 408 00:28:52,973 --> 00:28:56,549 and let's create the build method 409 00:28:56,549 --> 00:29:04,280 so build method, I like it to be the last method 410 00:29:04,280 --> 00:29:10,925 so the build method is the method that actually build the object 411 00:29:11,555 --> 00:29:14,608 so new user 412 00:29:15,648 --> 00:29:17,352 let's return the user 413 00:29:17,352 --> 00:29:19,075 and then I say 414 00:29:19,665 --> 00:29:23,185 add trips to user 415 00:29:23,215 --> 00:29:28,886 add friends to user 416 00:29:32,046 --> 00:29:37,885 it's always to cool to combine the method name and the parameter 417 00:29:37,885 --> 00:29:40,703 it makes it much easier to read it 418 00:29:40,703 --> 00:29:43,255 avoid duplication in names as well 419 00:29:43,255 --> 00:29:45,992 so let's do the trips first 420 00:29:45,992 --> 00:29:49,547 so for each 421 00:29:49,547 --> 00:29:52,000 here we're doing the trips 422 00:29:52,030 --> 00:29:56,039 so that's a trip that's a trip that's trips 423 00:29:56,239 --> 00:30:02,672 so user dot add trip, trip 424 00:30:04,262 --> 00:30:06,635 let's do the same thing for friends 425 00:30:06,635 --> 00:30:08,872 create add friends 426 00:30:11,152 --> 00:30:12,281 let's do 427 00:30:12,281 --> 00:30:14,648 for each 428 00:30:14,648 --> 00:30:17,045 so that's user 429 00:30:17,045 --> 00:30:19,935 that's friend 430 00:30:19,935 --> 00:30:21,935 friends 431 00:30:21,935 --> 00:30:28,482 user dot add friend friend 432 00:30:28,842 --> 00:30:30,781 awesome, cool 433 00:30:30,781 --> 00:30:35,595 so now, Infinitest saying everything is green 434 00:30:35,645 --> 00:30:39,761 so I can delete this 435 00:30:41,321 --> 00:30:43,652 and I can replace this one as well 436 00:30:43,652 --> 00:30:45,487 so let's replace this one 437 00:31:15,477 --> 00:31:18,578 awsome, let's comment that out 438 00:31:18,684 --> 00:31:21,945 so if I run everything, still green 439 00:31:21,945 --> 00:31:23,620 again, awesome 440 00:31:25,100 --> 00:31:29,763 so now my tests are slightly more readable 441 00:31:29,763 --> 00:31:33,512 so what I will do move this builder out 442 00:31:33,512 --> 00:31:34,984 so let's say 443 00:31:34,984 --> 00:31:37,004 move type to new file 444 00:31:39,074 --> 00:31:41,396 and basically what if you do 445 00:31:41,396 --> 00:31:47,582 if you just move this class the same folder where the TripServiceTest is 446 00:31:47,582 --> 00:31:49,475 for now it's good 447 00:31:50,345 --> 00:31:52,154 so now that is out 448 00:31:52,154 --> 00:31:56,413 static import this methods in here 449 00:31:56,413 --> 00:31:59,383 static import this methods in here 450 00:31:59,383 --> 00:32:01,997 so let's make code symmetric 451 00:32:01,997 --> 00:32:04,919 so both of them are symmetric 452 00:32:04,919 --> 00:32:09,426 and let's remove all the unutilized import 453 00:32:09,426 --> 00:32:12,078 so there's no unused imports anywhere 454 00:32:12,078 --> 00:32:13,618 so excellent 455 00:32:13,618 --> 00:32:17,101 so now I'm much much happier with my test 456 00:32:17,101 --> 00:32:19,723 because then I can read it properly 457 00:32:19,723 --> 00:32:22,667 and that's a great point to commit as well 458 00:32:22,667 --> 00:32:24,208 so let's see 459 00:32:24,294 --> 00:32:25,916 we got status 460 00:32:25,959 --> 00:32:28,606 git add 461 00:32:29,786 --> 00:32:31,473 git commit 462 00:32:31,473 --> 00:32:45,815 user builder created and used in trip service test 463 00:32:45,815 --> 00:32:48,650 cool, awesome 464 00:32:52,820 --> 00:32:56,242 so now we're finally ready to start refactoring this 465 00:32:56,242 --> 00:32:58,193 as we're saying before 466 00:32:58,193 --> 00:32:59,691 where was it, here 467 00:33:01,671 --> 00:33:06,793 we normally start testing from the shortest branch to the deepest 468 00:33:07,653 --> 00:33:10,463 and when we're doing refactoring it's the other way around 469 00:33:10,463 --> 00:33:12,645 you start from the deepest branch 470 00:33:13,585 --> 00:33:16,655 to the shortest delta branches 471 00:33:17,515 --> 00:33:19,346 the reason beneath is 472 00:33:19,346 --> 00:33:22,377 if you want to start refactoring in the middle of your code 473 00:33:22,377 --> 00:33:23,951 you need to understand everything 474 00:33:23,951 --> 00:33:25,312 and normally 475 00:33:26,522 --> 00:33:29,759 legacy code, they have global variable everywhere 476 00:33:29,759 --> 00:33:30,811 and dependencies 477 00:33:30,811 --> 00:33:33,691 set a flag in one place, checks it on the other 478 00:33:33,691 --> 00:33:36,744 but if you go straight to the deepest branch 479 00:33:36,744 --> 00:33:39,815 the deepest branch doesn't depend on anything 480 00:33:39,815 --> 00:33:43,251 it normally receives everything that it needs that is needs 481 00:33:43,251 --> 00:33:45,420 and then it does something with it 482 00:33:45,420 --> 00:33:48,494 if you're able to extract that 483 00:33:48,494 --> 00:33:52,511 refactor that the deepest branch from deepest to shortest 484 00:33:52,511 --> 00:33:54,001 you're code is start shrinking 485 00:33:54,001 --> 00:33:56,947 so let's look at the code 486 00:33:56,947 --> 00:33:59,734 so the deepest branch of the code 487 00:33:59,734 --> 00:34:01,748 as we discussed before is this one 488 00:34:01,748 --> 00:34:04,895 so to get to here 489 00:34:04,895 --> 00:34:06,554 I need this flag to be set 490 00:34:06,554 --> 00:34:08,675 the flag is set here 491 00:34:08,675 --> 00:34:11,568 the problem in this example in specific 492 00:34:11,568 --> 00:34:13,951 the deepest branch that is this line 493 00:34:13,951 --> 00:34:15,265 doesn't do much 494 00:34:15,265 --> 00:34:18,329 it just delegates to this one 495 00:34:18,329 --> 00:34:21,357 so I can re-do anything with one line 496 00:34:21,357 --> 00:34:24,675 so the second deepest branch is this one 497 00:34:26,405 --> 00:34:27,940 right it is this bit in here 498 00:34:27,940 --> 00:34:30,462 so let's go for this one 499 00:34:31,752 --> 00:34:34,119 one thing that is very very important 500 00:34:34,119 --> 00:34:36,187 when working with legacy code 501 00:34:36,187 --> 00:34:41,455 is to understand why the method is so big 502 00:34:41,455 --> 00:34:44,140 why is it so complicated? 503 00:34:44,140 --> 00:34:50,622 and normally it is because the method, of course, does too much 504 00:34:50,622 --> 00:34:52,904 that's why it has so many lines 505 00:34:52,904 --> 00:34:58,327 so it's important that instead of us trying to make the algorithm better 506 00:34:58,327 --> 00:35:01,172 or extract method in here 507 00:35:01,172 --> 00:35:02,789 we should ask ourselves 508 00:35:02,789 --> 00:35:04,780 does this responsibility 509 00:35:04,780 --> 00:35:07,905 does this behavior belong here? 510 00:35:07,905 --> 00:35:10,589 in this case, look at this 511 00:35:12,929 --> 00:35:14,464 if you look at this block 512 00:35:14,464 --> 00:35:23,856 so we go to the user object and asks for the friends 513 00:35:23,856 --> 00:35:27,998 so we get a list of friends out of the user object 514 00:35:28,000 --> 00:35:29,730 we iterate through it 515 00:35:29,730 --> 00:35:34,235 just to ask if the logged user is inside that collection or not 516 00:35:34,235 --> 00:35:36,417 so this is called feature envy 517 00:35:36,417 --> 00:35:40,028 it's kind of the trip serivce envies the user 518 00:35:40,153 --> 00:35:42,280 it wants to be the user class 519 00:35:42,280 --> 00:35:47,756 so what we could do here, we need to solve the feature envy 520 00:35:47,756 --> 00:35:52,852 if the user class has the collection of friends 521 00:35:52,852 --> 00:35:55,214 we should ask the user class, like 522 00:35:55,214 --> 00:35:58,851 user are you friends with this guy? 523 00:35:58,851 --> 00:36:03,443 so, let's try to move this behavior there 524 00:36:03,443 --> 00:36:04,617 so the first thing is 525 00:36:04,617 --> 00:36:06,771 let's look at the user class 526 00:36:06,771 --> 00:36:08,903 where's my user? 527 00:36:10,223 --> 00:36:12,892 so let's close this too 528 00:36:12,987 --> 00:36:15,264 so that's my user class 529 00:36:16,624 --> 00:36:18,724 let's create a test for it 530 00:36:18,724 --> 00:36:24,375 so my user class is here 531 00:36:24,375 --> 00:36:30,377 new class, let's say user test 532 00:36:30,377 --> 00:36:34,925 but I'm gonna put that in the test package of course 533 00:36:36,425 --> 00:36:40,103 so that will create my user test in here 534 00:36:40,103 --> 00:36:43,565 let's move my test here 535 00:36:43,565 --> 00:36:46,808 cool, so what do I want? 536 00:36:46,808 --> 00:36:53,380 I want this behavior here should be in this class 537 00:36:53,380 --> 00:36:55,445 I want to go to the user and say, 538 00:36:55,445 --> 00:36:58,190 "Are you friends with another user?" 539 00:36:58,190 --> 00:36:59,071 right? 540 00:36:59,071 --> 00:37:02,499 so, I'm gonna write this test 541 00:37:05,639 --> 00:37:11,453 should inform when users are not friends 542 00:37:11,453 --> 00:37:12,840 I'm gonna start with not friends 543 00:37:12,840 --> 00:37:15,149 because it is the easiest test that I can write 544 00:37:15,149 --> 00:37:16,521 this is the simplest one 545 00:37:18,879 --> 00:37:22,342 here I can use my builder 546 00:37:22,342 --> 00:37:34,841 user builder dot a user 547 00:37:35,049 --> 00:37:44,507 so let's say that this guy is friends with Bob 548 00:37:44,507 --> 00:37:49,077 right? let's do that 549 00:37:50,137 --> 00:37:54,424 and then in my test, I'm gonna say 550 00:37:55,284 --> 00:38:13,376 assert that user is friends with Paul is false 551 00:38:14,856 --> 00:38:20,712 so basically I want to create a user that is friend with Bob 552 00:38:20,712 --> 00:38:24,532 and of course if I ask this user if he's friend with Paul 553 00:38:24,532 --> 00:38:26,271 it should be false 554 00:38:26,271 --> 00:38:29,660 so let's create Bob and Paul 555 00:38:38,122 --> 00:38:39,691 let's create Paul as well 556 00:38:49,251 --> 00:38:53,430 so now that's the method that I want the user class have 557 00:38:53,430 --> 00:38:55,237 let's create it 558 00:39:00,187 --> 00:39:06,498 and of course the minimum behavior that I can have to satisfy the test 559 00:39:06,498 --> 00:39:07,878 is false 560 00:39:07,878 --> 00:39:10,412 so as soon as I save the false 561 00:39:10,412 --> 00:39:15,238 my Infinitest tells me that it's passing 562 00:39:15,238 --> 00:39:16,465 that's awesome, great 563 00:39:16,785 --> 00:39:23,269 so let's do the other case, when the users are friends 564 00:39:23,269 --> 00:39:34,910 it should inform when users are friends 565 00:39:38,320 --> 00:39:41,967 so I'm gonna borrow these guys here 566 00:39:41,967 --> 00:39:43,558 let's move that down 567 00:39:43,558 --> 00:39:47,434 and what I'm gonna do is 568 00:39:47,434 --> 00:39:51,050 you're also friend with Paul 569 00:39:51,050 --> 00:39:57,613 and I expect it, of course 570 00:39:58,383 --> 00:39:59,770 it should be true 571 00:39:59,770 --> 00:40:05,366 so my Infinitest are saying that it's not true 572 00:40:06,386 --> 00:40:08,331 now I'm gonna just implement 573 00:40:08,331 --> 00:40:11,363 just friends dot contain 574 00:40:13,363 --> 00:40:14,318 Paul doesn't work here 575 00:40:14,318 --> 00:40:17,836 let's say another user 576 00:40:25,876 --> 00:40:32,388 cool, so now I have my method in there 577 00:40:32,388 --> 00:40:36,011 awsome so of course that is covered 578 00:40:36,011 --> 00:40:38,305 there are ones that are not used in this one 579 00:40:38,305 --> 00:40:39,783 that's alright 580 00:40:41,153 --> 00:40:44,353 so this is a great point to commit 581 00:40:46,133 --> 00:40:47,683 git status 582 00:40:47,683 --> 00:40:49,330 git add 583 00:40:49,330 --> 00:40:51,004 so git commit 584 00:40:55,174 --> 00:41:02,884 is friends with method added to user 585 00:41:04,491 --> 00:41:06,012 awesome 586 00:41:07,892 --> 00:41:11,860 so now we can go back to our test 587 00:41:11,860 --> 00:41:19,098 just remove all the recorded code coverage marks 588 00:41:20,608 --> 00:41:24,471 now I have the user with the behavior that I want 589 00:41:24,981 --> 00:41:26,452 so when we start to refactoring 590 00:41:26,452 --> 00:41:28,791 we should try to stay in the green 591 00:41:28,791 --> 00:41:30,559 for as long as possible 592 00:41:30,559 --> 00:41:32,951 instead of going crazy in the refactoring 593 00:41:33,601 --> 00:41:35,733 and say I'm gonna change everything 594 00:41:35,733 --> 00:41:37,132 and then all the tests are broken 595 00:41:37,132 --> 00:41:40,346 we should, every single step that we make 596 00:41:40,346 --> 00:41:41,776 we should run our tests 597 00:41:41,790 --> 00:41:44,033 using Infinitest, is a way works well 598 00:41:44,033 --> 00:41:46,661 is fantastic because that 599 00:41:46,661 --> 00:41:49,680 if you make one move save it and it runs your test 600 00:41:49,680 --> 00:41:51,151 and then you know where you are 601 00:41:51,151 --> 00:41:54,845 and as soon as you make one move 602 00:41:54,845 --> 00:41:56,616 something is broken 603 00:41:56,616 --> 00:42:00,217 so your test shows the red in there 604 00:42:00,217 --> 00:42:03,782 you're one Ctrl+Z away to be back to green 605 00:42:03,782 --> 00:42:06,115 you just Ctrl+Z and save it 606 00:42:06,115 --> 00:42:07,306 you're back into green 607 00:42:07,306 --> 00:42:12,239 so let's try to make the smallest step that we can 608 00:42:12,239 --> 00:42:15,984 to do this refactoring and stay in the green, right? 609 00:42:18,764 --> 00:42:22,144 so what if I say 610 00:42:22,144 --> 00:42:28,766 what if I first of all move this boolean in here 611 00:42:28,766 --> 00:42:33,915 because it just used inside of the if statement so I can bring 612 00:42:33,915 --> 00:42:35,190 oh, there's another tip 613 00:42:35,190 --> 00:42:36,498 when working with legacy code 614 00:42:36,498 --> 00:42:40,318 normally you find variables declared all over the place 615 00:42:40,318 --> 00:42:42,358 try to bring them together 616 00:42:42,358 --> 00:42:48,219 try to put the blocks of code close each other 617 00:42:48,219 --> 00:42:51,620 if the variable is not used at the top 618 00:42:51,620 --> 00:42:53,038 it's just used at bottom 619 00:42:53,038 --> 00:42:54,439 but it's declared at the top 620 00:42:54,439 --> 00:42:55,852 bring that close 621 00:42:55,852 --> 00:42:58,205 because it ??? know where the blocks are 622 00:42:58,205 --> 00:43:00,850 and it makes you much easier to separate the code 623 00:43:00,850 --> 00:43:02,894 so now I could say 624 00:43:02,894 --> 00:43:10,145 is friend, I could say 625 00:43:10,145 --> 00:43:16,843 user is friends with logged user 626 00:43:16,843 --> 00:43:22,093 let's rename logged user to logged in user 627 00:43:22,093 --> 00:43:23,938 so that's how I think 628 00:43:23,938 --> 00:43:25,487 when you're dealing with legacy 629 00:43:25,487 --> 00:43:28,668 you find names are quite weird or not quite right 630 00:43:28,668 --> 00:43:29,997 as soon as you figured out where they are 631 00:43:29,997 --> 00:43:31,698 just rename it quickly 632 00:43:31,698 --> 00:43:33,238 so cool, as you can see 633 00:43:33,238 --> 00:43:37,850 you can keep an eye on the green bar here 634 00:43:37,850 --> 00:43:39,176 so every time that I saved it 635 00:43:39,176 --> 00:43:41,223 it's gonna run my test 636 00:43:41,223 --> 00:43:47,489 so now, I believe that is quite safe 637 00:43:47,489 --> 00:43:49,477 to do this and save 638 00:43:49,477 --> 00:43:52,536 so it ran my tests and that's green 639 00:43:52,536 --> 00:43:53,666 so now I can delete that 640 00:43:54,666 --> 00:43:57,265 so now that I can delete 641 00:43:58,345 --> 00:44:00,456 I maybe able to 642 00:44:09,923 --> 00:44:12,672 let's try to inline this 643 00:44:12,672 --> 00:44:14,054 awesome 644 00:44:14,584 --> 00:44:16,051 so that's cool 645 00:44:17,761 --> 00:44:23,281 so there is a quick win as well here 646 00:44:23,281 --> 00:44:25,697 for example, this guy here 647 00:44:26,387 --> 00:44:27,720 it's a guard clause 648 00:44:27,720 --> 00:44:30,448 we can transform this into guard clause 649 00:44:30,448 --> 00:44:31,482 what is a guard clause? 650 00:44:31,482 --> 00:44:33,328 as soon as parameter comes in 651 00:44:33,328 --> 00:44:35,865 you invalidate parameter and throw an exception 652 00:44:35,865 --> 00:44:37,430 that's the guard clause 653 00:44:37,430 --> 00:44:39,693 so what we can do 654 00:44:40,143 --> 00:44:44,895 let's transform that to guard clause 655 00:44:44,895 --> 00:44:46,005 we can get rid of if 656 00:44:48,265 --> 00:44:53,313 so if logged in user is null 657 00:44:56,293 --> 00:44:58,156 then 658 00:45:00,336 --> 00:45:02,558 let's throw an exception 659 00:45:03,308 --> 00:45:06,733 of course that this guy need to be up 660 00:45:09,003 --> 00:45:11,792 so as soon as I saved it 661 00:45:11,792 --> 00:45:13,585 so I'm still in the green 662 00:45:14,275 --> 00:45:19,897 and Eclipse kindly showing to me that this is dead code now 663 00:45:19,897 --> 00:45:23,988 so I can delete the entire if statement 664 00:45:27,578 --> 00:45:29,335 so if I save it 665 00:45:29,935 --> 00:45:30,577 awesome 666 00:45:30,577 --> 00:45:35,021 so I'm doing all these refactoring without going to the red 667 00:45:35,311 --> 00:45:36,583 not even a single time 668 00:45:36,583 --> 00:45:39,861 but even if I make a mistake and I go to the red 669 00:45:39,861 --> 00:45:42,506 what normally happens in the real world 670 00:45:42,506 --> 00:45:45,885 that's alright, I do a Ctrl+Z 671 00:45:45,885 --> 00:45:47,135 I'm back into green 672 00:45:47,135 --> 00:45:48,277 and I re-think what I'm doing 673 00:45:48,277 --> 00:45:50,529 sometimes you need to go to the red 674 00:45:50,529 --> 00:45:53,841 but I avoid it as much as I can 675 00:45:53,841 --> 00:45:57,490 so now we have two clear blocks in here 676 00:45:58,930 --> 00:46:06,300 the first block is about checking or validating the logged in user 677 00:46:06,300 --> 00:46:13,985 the second block is about getting the trips from the friend 678 00:46:13,985 --> 00:46:17,366 so we can do a few things slightly better in here 679 00:46:17,366 --> 00:46:20,223 so for example I could say 680 00:46:23,233 --> 00:46:25,919 getting rid of variables in legacy code 681 00:46:25,919 --> 00:46:28,994 is another thing that you should try to do 682 00:46:28,994 --> 00:46:32,182 because the less variables you have the easier it is 683 00:46:32,182 --> 00:46:36,525 even if you have some redundancy in there 684 00:46:36,525 --> 00:46:38,717 if you call method twice 685 00:46:38,717 --> 00:46:41,353 you may sacrifice performance for a while 686 00:46:41,923 --> 00:46:43,565 but getting rid of variable 687 00:46:43,565 --> 00:46:47,101 cause variables are the most people ??? in long method 688 00:46:47,101 --> 00:46:49,969 because they're set in many different places and reused 689 00:46:50,179 --> 00:46:51,814 if you can get rid of them 690 00:46:51,814 --> 00:46:55,658 and just invoke the same method over and over again 691 00:46:55,658 --> 00:46:58,209 it'll be easier to read all the code 692 00:46:58,209 --> 00:47:02,224 and then you do the optimization for ??? again, if you need to 693 00:47:02,224 --> 00:47:09,585 so for example, what I'm trying to do here is 694 00:47:16,185 --> 00:47:17,741 so saved it 695 00:47:17,741 --> 00:47:19,365 I'm still in the red 696 00:47:19,715 --> 00:47:25,885 so I believe that what I could even do is say 697 00:47:25,885 --> 00:47:27,197 return 698 00:47:29,817 --> 00:47:31,614 so I'm still in the green 699 00:47:32,604 --> 00:47:34,676 so return 700 00:47:35,576 --> 00:47:37,263 of course it don't need 701 00:47:37,263 --> 00:47:40,053 so if I save that I'm still in the green 702 00:47:40,053 --> 00:47:42,420 and I don't need the variable 703 00:47:42,420 --> 00:47:44,071 don't need that 704 00:47:44,071 --> 00:47:45,693 still in the green 705 00:47:45,993 --> 00:47:49,269 and now that I have symmetrical 706 00:47:49,269 --> 00:47:52,851 if I can use ternary operator 707 00:47:52,851 --> 00:47:57,614 so I could do that for exmple 708 00:48:11,854 --> 00:48:13,649 hopefully if I save that 709 00:48:13,649 --> 00:48:14,858 I'm still in the green 710 00:48:14,858 --> 00:48:15,849 awesome 711 00:48:15,849 --> 00:48:17,504 another thing is 712 00:48:17,504 --> 00:48:20,754 this variable here is used in two different places 713 00:48:20,754 --> 00:48:22,495 so let's inline that 714 00:48:22,495 --> 00:48:24,307 inline from here. yes, I can 715 00:48:24,307 --> 00:48:25,531 it's inlined in both places 716 00:48:25,531 --> 00:48:27,006 that's what I was talking about 717 00:48:27,006 --> 00:48:28,613 I got rid of the variable 718 00:48:29,093 --> 00:48:32,524 and of course I'm calling the method twice 719 00:48:32,524 --> 00:48:34,890 but I made my code a lot simpler 720 00:48:34,890 --> 00:48:36,489 of course if there's performance issue 721 00:48:36,503 --> 00:48:39,903 then you extract variables again all sort of stuff 722 00:48:39,903 --> 00:48:44,855 so that's awesome because now I'm much happier 723 00:48:44,935 --> 00:48:49,044 and one thing that I don't even like this guy here 724 00:48:51,124 --> 00:48:54,834 let's extract method in here, and say 725 00:48:54,834 --> 00:48:58,117 no trips, let's make it private 726 00:49:01,527 --> 00:49:03,867 so the cool thing about it is 727 00:49:05,647 --> 00:49:07,933 that for example 728 00:49:10,153 --> 00:49:11,771 if we look at the code 729 00:49:11,771 --> 00:49:13,959 if I look at my test now 730 00:49:15,379 --> 00:49:18,634 should throw an exception when user is not logged in 731 00:49:18,794 --> 00:49:20,523 get logged in user 732 00:49:20,523 --> 00:49:22,058 throw an exception 733 00:49:22,058 --> 00:49:27,100 should not return any trips when users are not friends 734 00:49:27,100 --> 00:49:29,738 if user is friends with logged in user 735 00:49:29,738 --> 00:49:31,027 no trips 736 00:49:31,027 --> 00:49:34,334 should return friend's trips when users are friends 737 00:49:34,334 --> 00:49:36,318 so if user is friend with logged in user 738 00:49:36,318 --> 00:49:37,851 trips by user 739 00:49:37,851 --> 00:49:44,936 so you end up saying the same language used in the test or test names 740 00:49:44,936 --> 00:49:46,228 being reflected in your code 741 00:49:46,228 --> 00:49:47,542 how your code is written 742 00:49:47,542 --> 00:49:49,916 that's one of the things that I want you to achieve 743 00:49:49,916 --> 00:49:55,244 so that's another good place to stop and commit 744 00:49:55,244 --> 00:49:56,765 so let's do that 745 00:49:56,765 --> 00:49:59,122 so git status 746 00:49:59,422 --> 00:50:02,157 git commit 747 00:50:03,357 --> 00:50:07,543 trip service refactored 748 00:50:09,193 --> 00:50:09,896 cool 749 00:50:12,336 --> 00:50:13,745 so that's awesome 750 00:50:15,385 --> 00:50:19,788 so we may think that this is good, right? 751 00:50:20,298 --> 00:50:21,518 we are done 752 00:50:22,362 --> 00:50:23,279 but NO. 753 00:50:23,279 --> 00:50:26,261 we are far from being done 754 00:50:27,841 --> 00:50:30,296 see, there's tiny piece of code 755 00:50:30,716 --> 00:50:35,407 but for example, we have enormous problems 756 00:50:36,267 --> 00:50:39,067 one of the problem is 757 00:50:39,067 --> 00:50:40,613 what we've done here is 758 00:50:40,613 --> 00:50:45,542 we took a piece of untested legacy code 759 00:50:45,902 --> 00:50:48,444 and then we wrote test straight 760 00:50:48,444 --> 00:50:50,107 and when we do that 761 00:50:50,107 --> 00:50:52,268 that's great, that's awesome 762 00:50:52,268 --> 00:50:55,851 cause then we feel confident that we can change it 763 00:50:55,851 --> 00:50:59,068 (???) 764 00:50:59,068 --> 00:51:02,047 but the drawback is that 765 00:51:02,047 --> 00:51:04,364 what if the design is wrong? 766 00:51:05,944 --> 00:51:07,730 cause if the design is wrong 767 00:51:08,480 --> 00:51:10,096 what we're doing when we write test 768 00:51:10,096 --> 00:51:12,518 we're perpetuating that design 769 00:51:13,058 --> 00:51:14,688 so we need to be very careful 770 00:51:14,688 --> 00:51:18,940 because if we're not very inclined to change the design 771 00:51:18,940 --> 00:51:22,334 and now we have a battery of test covering that stuff 772 00:51:22,334 --> 00:51:24,003 we're far less inclined now(???) 773 00:51:24,003 --> 00:51:25,452 because as soon as we start to change design 774 00:51:25,452 --> 00:51:26,917 you'll break all those tests 775 00:51:26,917 --> 00:51:28,572 so you need to be careful with that 776 00:51:28,572 --> 00:51:32,110 and why the design here is wrong? 777 00:51:32,500 --> 00:51:35,048 well, by the name 778 00:51:35,778 --> 00:51:41,252 I assume the trip service is a server side class 779 00:51:41,252 --> 00:51:42,733 belongs to the Model 780 00:51:44,023 --> 00:51:51,183 but then it has a dependency on the user session, right? 781 00:51:51,183 --> 00:51:57,021 so your Model shouldn't know anything about the web framework 782 00:51:57,021 --> 00:52:01,132 shouldn't know anything about http session or anything like that 783 00:52:01,692 --> 00:52:05,010 so, that's the problem with the design that this class has 784 00:52:05,010 --> 00:52:09,591 so we need to solve that 785 00:52:10,021 --> 00:52:11,818 one way to solve that is 786 00:52:11,818 --> 00:52:17,188 we should pass the logged in user as parameter to this method 787 00:52:17,188 --> 00:52:23,495 so now I'm gonna make sort of dangerous refactoring 788 00:52:23,495 --> 00:52:26,180 that it will be ok for this exercise 789 00:52:26,180 --> 00:52:28,543 but if you do that in a normal production environment 790 00:52:28,543 --> 00:52:29,661 you need to be very careful 791 00:52:29,661 --> 00:52:31,321 so I want to pass 792 00:52:31,321 --> 00:52:32,998 I'll try to do, as always 793 00:52:32,998 --> 00:52:35,200 baby steps, bit by bit 794 00:52:35,200 --> 00:52:40,283 so for example I want to pass the logged in user as parameter 795 00:52:40,283 --> 00:52:42,896 so what I can do is 796 00:52:42,896 --> 00:52:46,285 I go to refactor 797 00:52:46,285 --> 00:52:48,232 change method signature 798 00:52:48,232 --> 00:52:50,890 and I'm gonna add a new parameter 799 00:52:51,110 --> 00:52:52,994 I'm gonna call user 800 00:52:55,364 --> 00:52:59,251 logged in user, right? 801 00:52:59,251 --> 00:53:00,912 and the default is null 802 00:53:01,502 --> 00:53:04,340 so that's cool 803 00:53:04,399 --> 00:53:07,697 because eclipse does great job in refactoring 804 00:53:07,697 --> 00:53:09,612 IntelliJ does same 805 00:53:09,612 --> 00:53:12,628 so this guy was passed in as parameter 806 00:53:12,628 --> 00:53:14,533 it's not used anywhere else 807 00:53:14,533 --> 00:53:17,583 but it changed in my test 808 00:53:17,583 --> 00:53:22,745 it changed the method signature to pass null, everywhere, right? 809 00:53:23,215 --> 00:53:25,570 so that's cool, that's great 810 00:53:25,570 --> 00:53:28,626 the only problem is, for example 811 00:53:28,626 --> 00:53:31,506 this method here being a production method 812 00:53:31,506 --> 00:53:33,525 it's probably used 813 00:53:33,525 --> 00:53:37,261 or it's probably invoked by other classes 814 00:53:37,261 --> 00:53:44,536 and now all the other places where this method here is invoked 815 00:53:44,536 --> 00:53:47,355 the production code is passing null as well 816 00:53:47,355 --> 00:53:49,686 so you need to go back there and fix that 817 00:53:49,686 --> 00:53:51,897 so you just need to bear that in mind 818 00:53:52,857 --> 00:53:56,196 but for the sake of this exercise 819 00:53:58,496 --> 00:53:59,775 so what we want to do 820 00:53:59,775 --> 00:54:00,816 we want to do fix our test 821 00:54:00,816 --> 00:54:03,642 cause we don't want this nulls hanging in around 822 00:54:03,642 --> 00:54:05,126 and this is the logged user 823 00:54:05,126 --> 00:54:07,720 so I'm gonna pass here, a guest 824 00:54:07,720 --> 00:54:09,761 because that's what I would pass 825 00:54:11,751 --> 00:54:15,227 so as always I'm looking at my Infinitest 826 00:54:15,227 --> 00:54:22,113 so here I'm gonna pass my logged in user 827 00:54:22,113 --> 00:54:24,433 here I'm gonna pass 828 00:54:26,623 --> 00:54:30,336 yeah, I'm gonna pass my logged in user here 829 00:54:36,226 --> 00:54:37,497 so that's cool 830 00:54:37,497 --> 00:54:39,395 just to make sure that everything is ok 831 00:54:39,395 --> 00:54:40,717 so cool 832 00:54:41,787 --> 00:54:45,376 now I want to start using this parameter 833 00:54:46,706 --> 00:54:48,290 so what I'll do 834 00:54:49,110 --> 00:54:53,519 I'll just use the parameter 835 00:54:53,519 --> 00:54:59,106 I'm just gonna rename that to this 836 00:54:59,106 --> 00:55:04,050 rename that to this 837 00:55:04,050 --> 00:55:06,682 so this is the parameter now 838 00:55:06,682 --> 00:55:08,574 so if i save it 839 00:55:11,294 --> 00:55:14,088 and so all my tests are green 840 00:55:14,088 --> 00:55:16,350 so that means that this guy 841 00:55:16,350 --> 00:55:18,579 transform that in private 842 00:55:18,579 --> 00:55:22,050 so eclipse say that it's not been used 843 00:55:22,050 --> 00:55:25,290 so I can delete safely 844 00:55:26,340 --> 00:55:29,610 and of course, as soon as I delete my test 845 00:55:29,610 --> 00:55:32,305 I just need to delete this guy 846 00:55:32,305 --> 00:55:35,729 and everything is back to green 847 00:55:35,729 --> 00:55:37,238 so now I'm using the parameter 848 00:55:37,238 --> 00:55:40,050 I made my refactoring 849 00:55:40,930 --> 00:55:43,151 (???) thing that I can do is 850 00:55:43,151 --> 00:55:45,604 this logged in user 851 00:55:45,954 --> 00:55:48,526 I probably don't need that anymore 852 00:55:48,526 --> 00:55:54,684 so if I replace this one by these guys here 853 00:55:55,604 --> 00:55:58,927 and I put this guy here 854 00:56:02,057 --> 00:56:05,907 so one way to know if 855 00:56:05,907 --> 00:56:10,250 so now for example, eclipse is saying that this variable is not being used 856 00:56:10,250 --> 00:56:14,297 so now I can delete that 857 00:56:14,297 --> 00:56:16,931 and delete that 858 00:56:16,931 --> 00:56:19,144 delete that 859 00:56:19,144 --> 00:56:22,953 and everything is green 860 00:56:22,953 --> 00:56:26,395 so this is a perfect place to commit again 861 00:56:26,395 --> 00:56:29,167 oh, by the way, there is a warning here 862 00:56:29,167 --> 00:56:32,750 so should always get rid of the unused import 863 00:56:32,750 --> 00:56:35,137 because rubbish thing around (???) 864 00:56:35,137 --> 00:56:37,129 so craftsman ship is important 865 00:56:37,129 --> 00:56:38,836 keep it clean 866 00:56:39,826 --> 00:56:42,407 so cool, that's a great place to stop 867 00:56:42,407 --> 00:56:44,401 so let's say 868 00:56:45,171 --> 00:56:47,032 git commit 869 00:56:50,332 --> 00:57:00,543 logged in user passed into trip service 870 00:57:01,733 --> 00:57:03,620 cool, awesome 871 00:57:06,470 --> 00:57:08,876 so maybe now we're done 872 00:57:10,566 --> 00:57:12,997 sort of, sort of 873 00:57:12,997 --> 00:57:17,129 I still don't like this thing in here 874 00:57:17,899 --> 00:57:19,315 this trip dao thing 875 00:57:19,315 --> 00:57:21,255 I don't like the statical 876 00:57:21,255 --> 00:57:25,345 this statical makes me do this thing that 877 00:57:25,345 --> 00:57:30,169 as I said this is sort of intermediately step 878 00:57:30,175 --> 00:57:33,857 ideally I would inject trip dao in there 879 00:57:34,102 --> 00:57:36,248 using an instance method 880 00:57:36,346 --> 00:57:38,951 but because it's static method, I can't do much 881 00:57:38,951 --> 00:57:41,405 I can't really inject that, right? 882 00:57:41,405 --> 00:57:42,722 cause this is always 883 00:57:42,722 --> 00:57:46,333 you mean normally inject an instance not class 884 00:57:46,333 --> 00:57:48,188 so it doesn't work 885 00:57:48,188 --> 00:57:50,802 so I want to go further 886 00:57:50,802 --> 00:57:52,612 I want go get rid of this 887 00:57:52,612 --> 00:57:56,265 I want to have a instance method in my trip dao 888 00:57:56,265 --> 00:57:57,687 so let's open my trip dao 889 00:57:57,687 --> 00:57:59,088 let's see what it does 890 00:57:59,088 --> 00:58:00,423 so of course that in this case 891 00:58:00,423 --> 00:58:02,488 it is just like a toy example 892 00:58:02,488 --> 00:58:04,653 so you just throw an exception 893 00:58:06,113 --> 00:58:10,391 as I said before in a normal circumstance 894 00:58:10,391 --> 00:58:11,888 this would go to database 895 00:58:11,888 --> 00:58:12,956 or to distributed cache 896 00:58:12,956 --> 00:58:18,240 or whatever persistence mechanism you have 897 00:58:19,150 --> 00:58:21,292 so what I want to do 898 00:58:22,012 --> 00:58:28,973 I want to create an instance method for that 899 00:58:30,393 --> 00:58:35,448 so I'm gonna write a test for it 900 00:58:37,558 --> 00:58:39,052 let's say 901 00:58:42,938 --> 00:58:45,721 trip dao test 902 00:58:47,334 --> 00:58:49,164 let's put into test 903 00:58:51,646 --> 00:58:53,733 so this is an interesting one 904 00:58:55,573 --> 00:58:56,982 it's an interesting trick 905 00:58:58,132 --> 00:59:03,334 so I want an instance method 906 00:59:03,334 --> 00:59:08,534 that does everything that the static method does 907 00:59:11,530 --> 00:59:13,290 same behavior, just 908 00:59:15,661 --> 00:59:18,445 you could say, well, just remove static method 909 00:59:18,445 --> 00:59:22,546 just remove the static keyword from there 910 00:59:22,546 --> 00:59:23,902 yes, I could 911 00:59:23,902 --> 00:59:24,959 but if I do that 912 00:59:24,959 --> 00:59:27,574 I'll need to fix my entire code base 913 00:59:27,574 --> 00:59:31,951 because, let's assume that there are many classes in my application 914 00:59:32,331 --> 00:59:35,285 that are using this static method 915 00:59:35,285 --> 00:59:37,965 as soon as I transform this one into instance 916 00:59:37,965 --> 00:59:39,727 I'll break entire code base 917 00:59:39,727 --> 00:59:42,515 and that'll be much bigger refactoring to do 918 00:59:42,515 --> 00:59:45,498 and we want to do everything in small steps 919 00:59:46,068 --> 00:59:48,287 so what I'll do 920 00:59:49,166 --> 00:59:51,203 I create a test, let's say 921 00:59:51,203 --> 00:59:53,128 I'll just mimic this behavior 922 00:59:53,128 --> 00:59:54,929 so don't take this test too seriously 923 00:59:54,929 --> 00:59:57,434 just get the idea of what I'm doing 924 00:59:57,434 --> 01:00:00,785 but I'll just represent what this method currently does 925 01:00:00,785 --> 01:00:19,857 so should throw exception when retrieving user trips 926 01:00:21,302 --> 01:00:25,903 so I want this to throw an exception 927 01:00:27,903 --> 01:00:29,802 as I said 928 01:00:29,802 --> 01:00:33,701 ideally this would go to the database or something 929 01:00:33,732 --> 01:00:35,911 I'm just preserving the same behavior 930 01:00:35,911 --> 01:00:40,407 so dependent class call during unit test blah blah 931 01:00:40,407 --> 01:00:41,870 so that's the exception thrown 932 01:00:41,870 --> 01:00:44,679 but I want an instance method 933 01:00:44,679 --> 01:00:47,836 so just invoking the method should be enough 934 01:00:47,836 --> 01:00:49,233 so what I can do 935 01:00:49,233 --> 01:00:51,708 new trip dao 936 01:00:54,723 --> 01:01:06,018 let's call it trips by user 937 01:01:09,728 --> 01:01:13,185 so I want an instance method 938 01:01:14,845 --> 01:01:16,130 that throws an exception 939 01:01:16,130 --> 01:01:18,279 so I'm gonna create this method 940 01:01:18,769 --> 01:01:26,240 I'm gonna make it return the same thing as the other one 941 01:01:32,740 --> 01:01:34,967 so my test is failing, of course 942 01:01:34,967 --> 01:01:37,144 so now what I want this to do 943 01:01:37,144 --> 01:01:39,519 it should behave exactly like this static method 944 01:01:39,519 --> 01:01:43,096 so what I do is trip dao dot 945 01:01:45,036 --> 01:01:51,626 I just invoke from the instance method 946 01:01:51,626 --> 01:01:53,093 invoke the static one 947 01:01:54,003 --> 01:01:55,550 why do I do that? 948 01:01:55,550 --> 01:01:56,812 the cool thing is that 949 01:01:57,073 --> 01:02:02,570 as I start moving my code to use this one 950 01:02:04,790 --> 01:02:06,327 so now what I'm gonna do 951 01:02:06,327 --> 01:02:09,359 I'm gonna replace the trip service used the instance method 952 01:02:09,398 --> 01:02:11,230 and imagine that I start doing that 953 01:02:11,230 --> 01:02:13,165 for all the other class that used static 954 01:02:13,165 --> 01:02:19,120 until there's no class referencing the static method anymore 955 01:02:19,120 --> 01:02:20,042 and what I can do 956 01:02:20,042 --> 01:02:21,633 I just can copy this behavior 957 01:02:21,633 --> 01:02:24,325 paste it into here and delete the static method 958 01:02:24,325 --> 01:02:25,568 and then I'm done 959 01:02:25,568 --> 01:02:27,208 so that's the trick 960 01:02:27,208 --> 01:02:28,855 so going back to 961 01:02:28,855 --> 01:02:35,024 so now my trip dao has the instance method 962 01:02:35,024 --> 01:02:38,483 so what I need to do now 963 01:02:38,483 --> 01:02:43,623 is to have a reason to inject this trip dao in there 964 01:02:44,080 --> 01:02:46,023 so now I'm gonna 965 01:02:46,023 --> 01:02:48,757 there are quite of few ways of doing that like for example 966 01:02:48,757 --> 01:02:51,225 I could use normal dependency injection with no framework 967 01:02:51,225 --> 01:02:55,115 just pass the trip dao into the constructor of the trip service 968 01:02:55,115 --> 01:02:57,201 for example, that's one way of doing it 969 01:02:57,201 --> 01:02:59,487 and that's the simplest way 970 01:02:59,487 --> 01:03:02,776 as I know that majority of people that use java 971 01:03:02,776 --> 01:03:05,837 they use spring and they use mockito and stuff like that 972 01:03:05,898 --> 01:03:08,342 I'll show you how it would work in mockito 973 01:03:08,342 --> 01:03:10,695 but for now, if you don't use mockito 974 01:03:10,695 --> 01:03:11,659 then that's it 975 01:03:11,722 --> 01:03:16,509 create a constructor pass the trip dao to the constructor 976 01:03:16,843 --> 01:03:19,247 I'm just gonna do with mockito and spring 977 01:03:19,247 --> 01:03:21,762 just to show what you can do basically 978 01:03:21,826 --> 01:03:26,675 so I want now to have a broken test 979 01:03:26,675 --> 01:03:30,606 that justifies me to inject a trip dao in there 980 01:03:30,606 --> 01:03:33,269 so, I'm gonna say run with 981 01:03:33,315 --> 01:03:35,942 I'm gonna use JUnit with mockito 982 01:03:36,034 --> 01:03:37,271 mockito runner 983 01:03:37,344 --> 01:03:39,094 junit runner 984 01:03:42,064 --> 01:03:46,700 so if you don't use mockito and the junit in spring (???) 985 01:03:46,700 --> 01:03:48,409 maybe a bit complicated 986 01:03:48,409 --> 01:03:52,298 so I recommend that you read the documentation of all these frameworks 987 01:03:54,538 --> 01:04:00,891 so far, I've been using the testable trip service 988 01:04:00,891 --> 01:04:03,106 that class we created before 989 01:04:03,856 --> 01:04:06,761 now I want to start using the real one 990 01:04:06,761 --> 01:04:09,046 the real one and injecting 991 01:04:09,046 --> 01:04:12,568 cause I don't want these thing here anymore 992 01:04:12,568 --> 01:04:15,090 I don't want this madness here anymore 993 01:04:15,625 --> 01:04:18,617 I want to just to be able mock to my dependency 994 01:04:18,617 --> 01:04:21,305 so I'll create another 995 01:04:21,305 --> 01:04:23,773 do that in very small steps 996 01:04:24,223 --> 01:04:25,536 trip service 997 01:04:27,476 --> 01:04:36,756 I'll call for now real trip service new trip service 998 01:04:36,756 --> 01:04:38,409 that's the real one 999 01:04:38,409 --> 01:04:41,144 I'm gonna create a mock 1000 01:04:52,347 --> 01:04:54,688 I'm gonna create a mock to my dao 1001 01:05:00,488 --> 01:05:02,737 I'm gonna use mockito, to say 1002 01:05:04,357 --> 01:05:06,028 inject mocks 1003 01:05:06,028 --> 01:05:09,846 and I'm gonna spy on it 1004 01:05:11,246 --> 01:05:20,637 so basically it's out of scope for me to explain how mockito works 1005 01:05:20,637 --> 01:05:25,918 but basically in very short explanation 1006 01:05:25,918 --> 01:05:27,641 I'm creating the real class 1007 01:05:27,641 --> 01:05:30,405 I'm asking mockito to spy on the real class 1008 01:05:31,005 --> 01:05:35,162 and to inject all the mocks that this class may have 1009 01:05:35,162 --> 01:05:36,973 I create the mock in here 1010 01:05:36,973 --> 01:05:40,763 I just need to inform that this class is expecting this mock 1011 01:05:41,786 --> 01:05:43,753 so but before I go there 1012 01:05:43,753 --> 01:05:46,924 I'm gonna, now I'm using the real trip service in here 1013 01:05:46,924 --> 01:05:48,613 I'm gonna where it breaks 1014 01:05:48,613 --> 01:05:49,408 so for example 1015 01:05:49,408 --> 01:05:51,111 I can go bit by bit, I can say 1016 01:05:51,111 --> 01:05:55,042 real trip service and save 1017 01:05:56,352 --> 01:05:59,958 so my test still green 1018 01:06:00,678 --> 01:06:02,947 so because what I'm trying to do 1019 01:06:02,947 --> 01:06:05,562 I'm trying to get rid of this guy now 1020 01:06:05,917 --> 01:06:06,979 bit by bit 1021 01:06:07,579 --> 01:06:08,989 to replace with a real one 1022 01:06:09,569 --> 01:06:11,077 so real trip service 1023 01:06:11,346 --> 01:06:13,376 so if I do that 1024 01:06:13,916 --> 01:06:16,272 it works, cool 1025 01:06:16,279 --> 01:06:17,414 the reason it works 1026 01:06:17,414 --> 01:06:20,456 because none of those test that use, they go the dao 1027 01:06:20,456 --> 01:06:22,371 none of them get to this line 1028 01:06:23,686 --> 01:06:30,830 so this one, real trip service 1029 01:06:31,790 --> 01:06:34,690 so now it breaks, right? 1030 01:06:34,690 --> 01:06:36,614 that's what I was looking for 1031 01:06:36,614 --> 01:06:38,552 now it breaks because 1032 01:06:38,552 --> 01:06:44,196 I'm using in the test the real trip service 1033 01:06:44,196 --> 01:06:47,671 and that calls the static method in the trip dao 1034 01:06:47,671 --> 01:06:49,103 and that throws an exception 1035 01:06:49,103 --> 01:06:51,094 so cool, now I have a broken test 1036 01:06:51,094 --> 01:06:54,254 so I have a reason to change my production code 1037 01:06:56,634 --> 01:06:59,485 so what I'll do 1038 01:06:59,511 --> 01:07:02,190 I'll go to my production code and say 1039 01:07:02,190 --> 01:07:03,899 if I'm using spring 1040 01:07:04,269 --> 01:07:05,721 auto wired 1041 01:07:17,858 --> 01:07:21,982 so just import the auto wired 1042 01:07:21,982 --> 01:07:25,451 so imagine that if you gonna define the trip dao in a spring bean 1043 01:07:25,451 --> 01:07:26,527 in a xml 1044 01:07:26,527 --> 01:07:31,569 so private trip dao trip dao 1045 01:07:31,569 --> 01:07:32,703 awesome 1046 01:07:35,163 --> 01:07:36,834 maximize that 1047 01:07:38,194 --> 01:07:40,191 so cool 1048 01:07:40,215 --> 01:07:41,822 so what mockito will do 1049 01:07:41,822 --> 01:07:43,844 mockito will take this guy here 1050 01:07:43,850 --> 01:07:46,601 mymock and inject into this guy here 1051 01:07:49,427 --> 01:07:52,011 so now I need to start using that 1052 01:07:52,401 --> 01:07:54,745 so my test is broken 1053 01:07:54,985 --> 01:07:56,949 and I need to start using that 1054 01:07:56,949 --> 01:08:02,403 so in here, instead of using the 1055 01:08:04,893 --> 01:08:07,214 so if I run, I just run a test 1056 01:08:07,214 --> 01:08:09,919 just to show you the difference 1057 01:08:29,432 --> 01:08:30,887 run as 1058 01:08:32,749 --> 01:08:35,006 I keep pressing wrong button 1059 01:08:35,083 --> 01:08:39,907 so it's due to using the real dao, right? 1060 01:08:39,907 --> 01:08:45,323 so what we're gonna do is replace with the instance 1061 01:08:45,323 --> 01:08:49,473 and say use the instance method 1062 01:08:49,473 --> 01:08:51,457 instead of this classic one 1063 01:08:52,357 --> 01:08:55,749 so now if I run my test again 1064 01:08:55,749 --> 01:08:59,620 the error changed 1065 01:08:59,620 --> 01:09:02,634 so basically it's now using my mock 1066 01:09:03,144 --> 01:09:07,452 so if I just minimize it again 1067 01:09:07,452 --> 01:09:12,105 so now it's using my mock 1068 01:09:12,885 --> 01:09:17,721 and it says that the test expects two trips but it got zero 1069 01:09:17,901 --> 01:09:19,679 so that's what my test does 1070 01:09:19,679 --> 01:09:21,530 my test's expecting two 1071 01:09:23,560 --> 01:09:26,381 so what I need to do is 1072 01:09:26,381 --> 01:09:28,044 the reason that this is happening 1073 01:09:28,044 --> 01:09:31,146 because now my production code is using the mock 1074 01:09:31,146 --> 01:09:33,012 and the mock is not configured 1075 01:09:33,047 --> 01:09:37,679 so I just need to say that 1076 01:09:40,799 --> 01:09:44,475 given my trip dao 1077 01:09:44,475 --> 01:09:48,566 dot trips by user 1078 01:09:52,125 --> 01:09:57,811 so given that this method is invoked in my mock 1079 01:09:59,101 --> 01:10:04,745 it will return friend dot trips 1080 01:10:04,745 --> 01:10:07,646 so what I'm doing here 1081 01:10:07,646 --> 01:10:15,624 I'm configuring my mock to return the friend trips 1082 01:10:15,624 --> 01:10:19,122 exactly as the way we've done here 1083 01:10:19,122 --> 01:10:21,899 I'm doing in here just configuring my mock 1084 01:10:21,899 --> 01:10:25,128 so now as you can see my test is green 1085 01:10:26,618 --> 01:10:31,067 so this guy can go back to private now 1086 01:10:32,697 --> 01:10:36,721 and I don't need this method anymore 1087 01:10:38,831 --> 01:10:41,343 and if I run all my tests 1088 01:10:41,343 --> 01:10:43,306 my tests are all green 1089 01:10:43,306 --> 01:10:45,783 so that means I don't need this class anymore 1090 01:10:48,187 --> 01:10:50,952 so that means that I don't need this 1091 01:10:51,472 --> 01:10:53,967 and if I don't need this, I don't need this 1092 01:10:54,137 --> 01:10:57,254 and in this case, this guy is not been used anymore 1093 01:10:57,254 --> 01:10:58,874 I can delete 1094 01:11:00,164 --> 01:11:01,653 so now I can remove 1095 01:11:02,375 --> 01:11:04,350 I can rename my real trip service 1096 01:11:04,350 --> 01:11:05,770 because real means nothing 1097 01:11:05,770 --> 01:11:07,160 so when we're doing test 1098 01:11:07,160 --> 01:11:13,534 I've seen people calling variable like testee or mock (???) 1099 01:11:13,534 --> 01:11:14,950 call it what it is 1100 01:11:15,790 --> 01:11:20,208 it's a trip service. so it should be called trip service, right? 1101 01:11:20,248 --> 01:11:22,959 so now it's great because 1102 01:11:23,889 --> 01:11:27,427 I don't have that madness of test double class anymore 1103 01:11:27,427 --> 01:11:30,450 my test reads quite well 1104 01:11:30,940 --> 01:11:34,809 and so just make sure that everything is green 1105 01:11:34,809 --> 01:11:37,683 I can even go there and say 1106 01:11:43,523 --> 01:11:45,857 so validate logged in user 1107 01:11:47,367 --> 01:11:49,132 so now as I said 1108 01:11:49,132 --> 01:11:53,577 I can close all my test methods 1109 01:11:55,374 --> 01:12:00,128 and we can read this block here and say 1110 01:12:00,155 --> 01:12:02,537 should throw an exception when user is not logged in 1111 01:12:02,537 --> 01:12:05,117 that's part of the validation of the logged in user 1112 01:12:05,907 --> 01:12:08,911 should not return any trips when users are not friends 1113 01:12:08,911 --> 01:12:12,822 so if the users are not friends returns no trips 1114 01:12:13,742 --> 01:12:17,719 so should return friend trips 1115 01:12:17,719 --> 01:12:18,992 when users are friend 1116 01:12:18,992 --> 01:12:22,244 so if the user is friends with the logged in user 1117 01:12:22,244 --> 01:12:24,023 just return the trips 1118 01:12:28,303 --> 01:12:31,446 even this getter method here is not great 1119 01:12:31,446 --> 01:12:35,727 so get trips by user so that could say 1120 01:12:36,237 --> 01:12:39,141 get friend trips 1121 01:12:39,881 --> 01:12:41,946 that sounds much better 1122 01:12:42,486 --> 01:12:45,946 this guy could be 1123 01:12:48,715 --> 01:12:50,672 friend as well 1124 01:12:51,982 --> 01:12:54,166 or something like that 1125 01:12:55,966 --> 01:12:59,460 so you can play with these things now 1126 01:12:59,460 --> 01:13:02,282 that you have all the code coverage 1127 01:13:02,652 --> 01:13:07,155 so basically that's another great point to stop 1128 01:13:07,155 --> 01:13:09,231 so git status 1129 01:13:09,962 --> 01:13:12,333 git add . 1130 01:13:14,535 --> 01:13:17,504 so git commit 1131 01:13:19,248 --> 01:13:26,593 trip dao injected into trip service 1132 01:13:27,803 --> 01:13:30,958 so this it it 1133 01:13:30,958 --> 01:13:32,459 that's normally 1134 01:13:33,187 --> 01:13:35,400 that's what all the things that you can do 1135 01:13:35,400 --> 01:13:37,326 with legacy code in a very safe way 1136 01:13:39,116 --> 01:13:41,296 I can show you 1137 01:13:46,726 --> 01:13:50,083 I have original trip service somewhere in here 1138 01:13:50,116 --> 01:13:53,739 so you can compare 1139 01:13:53,739 --> 01:14:03,367 so we went from this to this 1140 01:14:03,367 --> 01:14:05,911 and of course that 1141 01:14:06,009 --> 01:14:09,426 it took me just an hour to do that 1142 01:14:09,426 --> 01:14:12,505 but it's because I'm recording this screen cast 1143 01:14:12,505 --> 01:14:15,860 but as soon as you're comfortable with all these techniques 1144 01:14:15,860 --> 01:14:19,766 this probably would have taken me in a normal day like 20 minutes 1145 01:14:19,766 --> 01:14:21,925 so it's just like 1146 01:14:21,925 --> 01:14:24,337 as soon as you're aware of what is available to you 1147 01:14:24,367 --> 01:14:25,976 then you just practice it 1148 01:14:25,976 --> 01:14:29,387 and then it makes things much easier 1149 01:14:29,387 --> 01:14:32,153 and just as a reminder 1150 01:14:32,153 --> 01:14:35,241 every time that you're working with legacy code 1151 01:14:35,241 --> 01:14:40,080 your first test should never be the one that goes to the deepest branch 1152 01:14:40,080 --> 01:14:42,249 always start from shortest branch 1153 01:14:42,249 --> 01:14:44,183 from the shortest to the deepeset 1154 01:14:44,183 --> 01:14:47,002 write your test in this order from the shortest to the deepest 1155 01:14:47,002 --> 01:14:51,176 it's easier because the test will help you to understand what the code does 1156 01:14:51,176 --> 01:14:55,301 and it will help you to build the test data 1157 01:14:55,301 --> 01:14:58,381 bit by bit as you dive deep into the code 1158 01:14:58,381 --> 01:14:59,975 when you're refactoring 1159 01:14:59,975 --> 01:15:01,159 do the other way around 1160 01:15:01,159 --> 01:15:02,909 find the deepest branch 1161 01:15:02,909 --> 01:15:05,179 and start extracting method from there 1162 01:15:05,179 --> 01:15:08,423 starting put in that behavior into different classes 1163 01:15:08,423 --> 01:15:11,398 and then all of sudden your code will start 1164 01:15:11,398 --> 01:15:14,426 collapsing and getting smaller and smaller 1165 01:15:14,426 --> 01:15:16,958 because you're removing the internal parts 1166 01:15:18,598 --> 01:15:23,509 so try to write readable and maintainable code 1167 01:15:24,036 --> 01:15:25,850 try to have the domain language in there 1168 01:15:25,850 --> 01:15:27,586 try to capture that 1169 01:15:27,586 --> 01:15:29,986 like using things like guess(???) and stuff like that 1170 01:15:29,986 --> 01:15:31,628 so as part of the domain 1171 01:15:31,628 --> 01:15:36,872 try to bring the domain language into your test and into your code 1172 01:15:36,872 --> 01:15:42,650 the language spoken in the test and the code and used it with your BA should be the same 1173 01:15:43,180 --> 01:15:46,269 try to have simplicity 1174 01:15:46,269 --> 01:15:49,058 know your shortcuts, frameworks like 1175 01:15:49,058 --> 01:15:51,219 try to be fast 1176 01:15:51,669 --> 01:15:55,732 configure your environment so you can with a few shortcuts 1177 01:15:55,732 --> 01:15:57,959 create test methods and classes and all sort of stuff 1178 01:15:57,959 --> 01:16:00,063 and do the refactorings 1179 01:16:00,063 --> 01:16:03,564 and as I said working in very small increments 1180 01:16:03,564 --> 01:16:04,718 commit often 1181 01:16:04,718 --> 01:16:07,210 I mean if you're using git and stuff like that 1182 01:16:07,680 --> 01:16:10,405 because if you make mistake 1183 01:16:10,405 --> 01:16:12,884 Ctrl+Z or git reset hard 1184 01:16:12,884 --> 01:16:14,827 you go back to previous commit 1185 01:16:14,827 --> 01:16:16,957 and you're back into the green 1186 01:16:16,957 --> 01:16:18,685 be brave 1187 01:16:18,685 --> 01:16:22,015 now you know a lot of things like 1188 01:16:22,015 --> 01:16:26,903 all these small tricks that we learned today 1189 01:16:26,903 --> 01:16:31,416 we'll make probably 99% of all your classes testable 1190 01:16:31,416 --> 01:16:33,171 so just be brave 1191 01:16:33,171 --> 01:16:35,503 use it, and 1192 01:16:36,823 --> 01:16:39,755 always leave the campground cleaner than you found it 1193 01:16:39,755 --> 01:16:41,367 so that's the boy scout rule 1194 01:16:41,367 --> 01:16:42,708 no broken windows 1195 01:16:42,708 --> 01:16:44,413 if it's smelly 1196 01:16:44,413 --> 01:16:47,959 if it's not very well written 1197 01:16:47,959 --> 01:16:49,088 just refactor it 1198 01:16:49,088 --> 01:16:50,773 just go for it 1199 01:16:50,773 --> 01:16:53,135 yep, so I hope you enjoyed it 1200 01:16:53,795 --> 01:16:55,701 that's it 1201 01:16:55,701 --> 01:17:00,519 so you can find this trip service kata in my github 1202 01:17:00,519 --> 01:17:03,843 so just go to github sandromancuso trip service kata 1203 01:17:03,843 --> 01:17:05,622 that's it, hope you enjoyed it 1204 01:17:05,622 --> 01:17:07,482 thank you