[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:02.39,0:00:06.93,Default,,0000,0000,0000,,Hi, my name is sandro mancuso Dialogue: 0,0:00:06.93,0:00:09.53,Default,,0000,0000,0000,,in this screen cast Dialogue: 0,0:00:09.53,0:00:15.86,Default,,0000,0000,0000,,we're gonna take a piece of existing code without test Dialogue: 0,0:00:15.86,0:00:18.12,Default,,0000,0000,0000,,we're gonna write tests for it first Dialogue: 0,0:00:18.12,0:00:20.57,Default,,0000,0000,0000,,and when it is 100% covered Dialogue: 0,0:00:20.57,0:00:23.57,Default,,0000,0000,0000,,then we're gonna refactor it to make it better Dialogue: 0,0:00:23.57,0:00:25.59,Default,,0000,0000,0000,,so, the business requirements are Dialogue: 0,0:00:25.59,0:00:28.61,Default,,0000,0000,0000,,imagine a social networking website for travellers Dialogue: 0,0:00:28.61,0:00:33.60,Default,,0000,0000,0000,,so, you need to be logged in to see any type of content Dialogue: 0,0:00:33.60,0:00:35.55,Default,,0000,0000,0000,,and as soon as you logged in Dialogue: 0,0:00:35.55,0:00:37.46,Default,,0000,0000,0000,,if you want to see someone else's trips Dialogue: 0,0:00:37.46,0:00:39.89,Default,,0000,0000,0000,,you need to be friends with this person Dialogue: 0,0:00:39.89,0:00:42.12,Default,,0000,0000,0000,,it's kind of like your facebook stuff Dialogue: 0,0:00:42.12,0:00:45.55,Default,,0000,0000,0000,,so, if you're friends with someone you can see this person's trip Dialogue: 0,0:00:45.55,0:00:47.68,Default,,0000,0000,0000,,otherwise, you can't Dialogue: 0,0:00:49.27,0:00:51.17,Default,,0000,0000,0000,,so, but there are a few rules Dialogue: 0,0:00:51.17,0:00:56.13,Default,,0000,0000,0000,,we can not touch production code if it's not covered by tests Dialogue: 0,0:00:57.22,0:01:03.18,Default,,0000,0000,0000,,so, as we know, sometimes we should write test for existing code Dialogue: 0,0:01:03.18,0:01:04.98,Default,,0000,0000,0000,,we need to change the existing code Dialogue: 0,0:01:04.98,0:01:10.26,Default,,0000,0000,0000,,so the only exception to this rule is that you can use automatic refactoring Dialogue: 0,0:01:10.26,0:01:14.71,Default,,0000,0000,0000,,by our IDE, never type into the file Dialogue: 0,0:01:16.06,0:01:19.63,Default,,0000,0000,0000,,so, one approach that we gonna take is Dialogue: 0,0:01:19.63,0:01:24.11,Default,,0000,0000,0000,,imagine that this is how your code looks like Dialogue: 0,0:01:24.11,0:01:29.23,Default,,0000,0000,0000,,instead of trying to go to write test from the deepest branch Dialogue: 0,0:01:29.50,0:01:34.44,Default,,0000,0000,0000,,we're gonna choose the shortest branch of the code and write a test for that Dialogue: 0,0:01:35.15,0:01:39.57,Default,,0000,0000,0000,,and then we look at the second shortest branch Dialogue: 0,0:01:39.57,0:01:41.47,Default,,0000,0000,0000,,and then write a test for that Dialogue: 0,0:01:41.47,0:01:45.42,Default,,0000,0000,0000,,cause that gives us the ability to test by test Dialogue: 0,0:01:45.53,0:01:47.77,Default,,0000,0000,0000,,understand what our code does Dialogue: 0,0:01:47.88,0:01:54.29,Default,,0000,0000,0000,,and also we build up our test suite so we can get to the deepest branch Dialogue: 0,0:01:54.29,0:01:58.38,Default,,0000,0000,0000,,if we start to write a test according to the deepest branch Dialogue: 0,0:01:58.38,0:02:00.21,Default,,0000,0000,0000,,or trying to test the deepest branch Dialogue: 0,0:02:00.21,0:02:06.10,Default,,0000,0000,0000,,normally we need to create a massive setup to get there Dialogue: 0,0:02:06.93,0:02:09.39,Default,,0000,0000,0000,,so, we need to understand entire code base Dialogue: 0,0:02:09.39,0:02:13.20,Default,,0000,0000,0000,,so we prefer to do from the shortest branch to the deepest Dialogue: 0,0:02:13.20,0:02:15.26,Default,,0000,0000,0000,,let's see some code Dialogue: 0,0:02:15.26,0:02:20.09,Default,,0000,0000,0000,,so this is the trip service class Dialogue: 0,0:02:20.77,0:02:23.82,Default,,0000,0000,0000,,this is a server side class Dialogue: 0,0:02:24.56,0:02:27.06,Default,,0000,0000,0000,,and basically what it does is Dialogue: 0,0:02:27.06,0:02:28.100,Default,,0000,0000,0000,,it has a get trips by user Dialogue: 0,0:02:28.100,0:02:31.17,Default,,0000,0000,0000,,receive a user in there Dialogue: 0,0:02:31.17,0:02:35.98,Default,,0000,0000,0000,,so it checks the user session Dialogue: 0,0:02:35.98,0:02:38.13,Default,,0000,0000,0000,,gets the user that is logged in Dialogue: 0,0:02:39.20,0:02:44.80,Default,,0000,0000,0000,,then if the user is not logged in it throws an exception Dialogue: 0,0:02:44.80,0:02:50.73,Default,,0000,0000,0000,,if the user is logged in then Dialogue: 0,0:02:50.73,0:02:57.14,Default,,0000,0000,0000,,check if the logged in user is friends with the user passed as parameter Dialogue: 0,0:02:57.14,0:02:59.86,Default,,0000,0000,0000,,and if they're friends then I can retrieve Dialogue: 0,0:02:59.86,0:03:03.88,Default,,0000,0000,0000,,the list of trips for the user passed through parameter Dialogue: 0,0:03:03.88,0:03:07.75,Default,,0000,0000,0000,,so a bit confusing for now but what I'm gonna do Dialogue: 0,0:03:07.75,0:03:11.29,Default,,0000,0000,0000,,let's start writing test for it Dialogue: 0,0:03:11.29,0:03:14.53,Default,,0000,0000,0000,,may I just split the screen Dialogue: 0,0:03:14.53,0:03:17.59,Default,,0000,0000,0000,,that's normally how I prefer to code Dialogue: 0,0:03:17.59,0:03:19.72,Default,,0000,0000,0000,,I normally split my screen into two Dialogue: 0,0:03:19.72,0:03:21.81,Default,,0000,0000,0000,,I have my production code in one side Dialogue: 0,0:03:21.81,0:03:23.30,Default,,0000,0000,0000,,my test on the other side Dialogue: 0,0:03:23.30,0:03:27.09,Default,,0000,0000,0000,,then I don't need to keep switching from one to another Dialogue: 0,0:03:27.09,0:03:31.04,Default,,0000,0000,0000,,so that's my favorite way of coding Dialogue: 0,0:03:31.04,0:03:33.92,Default,,0000,0000,0000,,so, the first thing that we do Dialogue: 0,0:03:33.92,0:03:35.85,Default,,0000,0000,0000,,we just look for the shortest branch Dialogue: 0,0:03:35.85,0:03:37.07,Default,,0000,0000,0000,,we can ignore entire thing Dialogue: 0,0:03:37.07,0:03:39.20,Default,,0000,0000,0000,,I don't care what this does for now Dialogue: 0,0:03:39.39,0:03:41.51,Default,,0000,0000,0000,,for me, when I'm working with legacy code Dialogue: 0,0:03:41.51,0:03:42.99,Default,,0000,0000,0000,,the first thing that I do is Dialogue: 0,0:03:43.10,0:03:44.61,Default,,0000,0000,0000,,if I want to see what this code does Dialogue: 0,0:03:44.61,0:03:46.15,Default,,0000,0000,0000,,I look for the shortest branch Dialogue: 0,0:03:46.15,0:03:49.34,Default,,0000,0000,0000,,if the logged user is different from null Dialogue: 0,0:03:49.38,0:03:51.08,Default,,0000,0000,0000,,then it throws an exception Dialogue: 0,0:03:51.08,0:03:53.78,Default,,0000,0000,0000,,so if it is not logged in throws an exception Dialogue: 0,0:03:53.78,0:03:56.83,Default,,0000,0000,0000,,so let's write a test to see if that's true Dialogue: 0,0:03:57.47,0:04:12.54,Default,,0000,0000,0000,,so, should throw an exception when user is not logged in Dialogue: 0,0:04:13.18,0:04:16.50,Default,,0000,0000,0000,,let's put the exception here Dialogue: 0,0:04:16.54,0:04:22.55,Default,,0000,0000,0000,,expect it, user not logged in exception Dialogue: 0,0:04:24.40,0:04:27.41,Default,,0000,0000,0000,,so let's create the trip service Dialogue: 0,0:04:33.45,0:04:34.84,Default,,0000,0000,0000,,import that Dialogue: 0,0:04:35.24,0:04:37.16,Default,,0000,0000,0000,,now what we should do Dialogue: 0,0:04:37.16,0:04:41.64,Default,,0000,0000,0000,,trip service dot Dialogue: 0,0:04:42.28,0:04:44.35,Default,,0000,0000,0000,,get trips by user Dialogue: 0,0:04:44.35,0:04:46.62,Default,,0000,0000,0000,,pass as null here for now Dialogue: 0,0:04:50.29,0:04:52.19,Default,,0000,0000,0000,,I'm using Infinitest Dialogue: 0,0:04:52.20,0:04:55.98,Default,,0000,0000,0000,,so this red bar here basically show Dialogue: 0,0:04:55.98,0:04:59.21,Default,,0000,0000,0000,,everytime that I save my test or my production code Dialogue: 0,0:04:59.21,0:05:00.92,Default,,0000,0000,0000,,it runs my test for me Dialogue: 0,0:05:00.92,0:05:02.90,Default,,0000,0000,0000,,so I don't need to keep trying with my hands Dialogue: 0,0:05:02.90,0:05:05.42,Default,,0000,0000,0000,,this should be in theory Dialogue: 0,0:05:05.75,0:05:06.54,Default,,0000,0000,0000,,green Dialogue: 0,0:05:06.75,0:05:09.62,Default,,0000,0000,0000,,but something is happening Dialogue: 0,0:05:09.62,0:05:19.82,Default,,0000,0000,0000,,so if I run junit by hand Dialogue: 0,0:05:19.82,0:05:22.57,Default,,0000,0000,0000,,basically what's happening is Dialogue: 0,0:05:22.57,0:05:27.70,Default,,0000,0000,0000,,this should throw user not loggedn in exception Dialogue: 0,0:05:27.70,0:05:30.64,Default,,0000,0000,0000,,it's expecting user not logged in exception Dialogue: 0,0:05:30.64,0:05:34.89,Default,,0000,0000,0000,,but it's throwing a dependent a class during blah blah Dialogue: 0,0:05:34.93,0:05:37.67,Default,,0000,0000,0000,,so basically what's happening is Dialogue: 0,0:05:41.12,0:05:46.69,Default,,0000,0000,0000,,when this line here is executed Dialogue: 0,0:05:49.11,0:05:55.19,Default,,0000,0000,0000,,so when I say user session, get instance, get logged user Dialogue: 0,0:05:56.19,0:05:57.84,Default,,0000,0000,0000,,the user session Dialogue: 0,0:05:57.84,0:06:00.84,Default,,0000,0000,0000,,I did that on purpose of course Dialogue: 0,0:06:00.84,0:06:02.61,Default,,0000,0000,0000,,throws an exception Dialogue: 0,0:06:03.30,0:06:06.22,Default,,0000,0000,0000,,basically because in a unit test Dialogue: 0,0:06:06.22,0:06:10.75,Default,,0000,0000,0000,,we shouldn't be invoking other classes Dialogue: 0,0:06:11.31,0:06:14.65,Default,,0000,0000,0000,,because this may have the dependency of http session Dialogue: 0,0:06:14.65,0:06:18.03,Default,,0000,0000,0000,,it could go to the database to retrieve stuff Dialogue: 0,0:06:18.03,0:06:19.85,Default,,0000,0000,0000,,so we don't want that Dialogue: 0,0:06:20.56,0:06:22.98,Default,,0000,0000,0000,,so we need to break these dependencies Dialogue: 0,0:06:24.24,0:06:26.11,Default,,0000,0000,0000,,the problem that we have is Dialogue: 0,0:06:26.11,0:06:27.73,Default,,0000,0000,0000,,this is a singleton Dialogue: 0,0:06:27.73,0:06:32.60,Default,,0000,0000,0000,,and I cannot mock it right now Dialogue: 0,0:06:32.60,0:06:37.84,Default,,0000,0000,0000,,so I can't inject it, I can't type inside this trip service Dialogue: 0,0:06:38.94,0:06:41.90,Default,,0000,0000,0000,,but I need to find a way to get rid of it Dialogue: 0,0:06:41.90,0:06:44.14,Default,,0000,0000,0000,,I need to find a way to mock that Dialogue: 0,0:06:44.14,0:06:48.32,Default,,0000,0000,0000,,so the only things that I can do, as I said before Dialogue: 0,0:06:48.32,0:06:50.68,Default,,0000,0000,0000,,is I need to use automated refactoring Dialogue: 0,0:06:50.68,0:06:51.69,Default,,0000,0000,0000,,but I cannot not type Dialogue: 0,0:06:51.69,0:06:53.62,Default,,0000,0000,0000,,so here what I'm gonna do Dialogue: 0,0:06:53.62,0:06:55.55,Default,,0000,0000,0000,,I'm gonna create a seam Dialogue: 0,0:06:55.55,0:06:59.96,Default,,0000,0000,0000,,so seam is the division of where the two classes Dialogue: 0,0:06:59.96,0:07:02.74,Default,,0000,0000,0000,,the seam is where two classes meet Dialogue: 0,0:07:02.74,0:07:04.80,Default,,0000,0000,0000,,the trip service and the user session Dialogue: 0,0:07:04.80,0:07:06.47,Default,,0000,0000,0000,,so I'm gonna create this seam Dialogue: 0,0:07:06.47,0:07:09.40,Default,,0000,0000,0000,,so what I'm gonna do, I'm gonna create a method Dialogue: 0,0:07:09.99,0:07:14.96,Default,,0000,0000,0000,,saying get logged in user Dialogue: 0,0:07:16.51,0:07:18.28,Default,,0000,0000,0000,,and I will make that protected Dialogue: 0,0:07:19.15,0:07:27.02,Default,,0000,0000,0000,,so I just isolated the bit that goes to the other class Dialogue: 0,0:07:27.54,0:07:29.47,Default,,0000,0000,0000,,and that's my seam Dialogue: 0,0:07:30.01,0:07:33.73,Default,,0000,0000,0000,,so now what I can do as an intermediary step Dialogue: 0,0:07:33.73,0:07:44.85,Default,,0000,0000,0000,,I can create a private class, testable trip service Dialogue: 0,0:07:44.85,0:07:49.39,Default,,0000,0000,0000,,that extends the trip service Dialogue: 0,0:07:52.19,0:07:54.43,Default,,0000,0000,0000,,so what I do Dialogue: 0,0:07:54.47,0:08:03.56,Default,,0000,0000,0000,,I override the get logged in user Dialogue: 0,0:08:03.83,0:08:07.33,Default,,0000,0000,0000,,and I make it return null Dialogue: 0,0:08:10.58,0:08:17.81,Default,,0000,0000,0000,,and in my test, I replace the trip service by testable trip service Dialogue: 0,0:08:23.66,0:08:28.53,Default,,0000,0000,0000,,and so if I try to run that Dialogue: 0,0:08:28.57,0:08:32.21,Default,,0000,0000,0000,,now I have it green as you can see here Dialogue: 0,0:08:32.21,0:08:35.44,Default,,0000,0000,0000,,my infinitest somtimes goes crazy Dialogue: 0,0:08:35.54,0:08:39.02,Default,,0000,0000,0000,,sometimes I can trust, sometimes I cannot trust Dialogue: 0,0:08:39.02,0:08:44.92,Default,,0000,0000,0000,,in this case it was red but my tests are green now Dialogue: 0,0:08:44.96,0:08:49.50,Default,,0000,0000,0000,,so in theory I should be happy with that Dialogue: 0,0:08:49.82,0:08:53.47,Default,,0000,0000,0000,,just to confirm, so my test is green Dialogue: 0,0:08:54.21,0:08:58.61,Default,,0000,0000,0000,,and if I run my code coverage Dialogue: 0,0:08:59.53,0:09:05.99,Default,,0000,0000,0000,,so I make sure that I'm testing the shortest branch Dialogue: 0,0:09:05.99,0:09:08.61,Default,,0000,0000,0000,,so that's another good tip Dialogue: 0,0:09:08.61,0:09:11.22,Default,,0000,0000,0000,,cause every time that I work with legacy code Dialogue: 0,0:09:11.22,0:09:13.14,Default,,0000,0000,0000,,I always use code coverage Dialogue: 0,0:09:13.14,0:09:15.10,Default,,0000,0000,0000,,so lots people thing code coverage ... Dialogue: 0,0:09:15.10,0:09:16.95,Default,,0000,0000,0000,,ah... it's test coverage Dialogue: 0,0:09:16.95,0:09:18.73,Default,,0000,0000,0000,,I don't care about the percentage Dialogue: 0,0:09:18.73,0:09:22.71,Default,,0000,0000,0000,,the important thing for me here is, when I'm working with legacies Dialogue: 0,0:09:22.71,0:09:27.92,Default,,0000,0000,0000,,is my test covering the branch that I thought it would cover Dialogue: 0,0:09:27.92,0:09:30.90,Default,,0000,0000,0000,,because this avoid the false positives and negatives Dialogue: 0,0:09:30.90,0:09:32.97,Default,,0000,0000,0000,,so I know exactly what I'm doing now Dialogue: 0,0:09:33.00,0:09:35.12,Default,,0000,0000,0000,,so that's cool Dialogue: 0,0:09:35.12,0:09:41.66,Default,,0000,0000,0000,,so let's remove that the code ceverage Dialogue: 0,0:09:47.29,0:09:50.29,Default,,0000,0000,0000,,however this test is far from being good Dialogue: 0,0:09:50.29,0:09:52.59,Default,,0000,0000,0000,,because look at this Dialogue: 0,0:09:52.59,0:09:56.00,Default,,0000,0000,0000,,should throw an exception when user is not logged in Dialogue: 0,0:09:57.45,0:10:01.81,Default,,0000,0000,0000,,this test is all about the user not being logged in Dialogue: 0,0:10:02.87,0:10:05.07,Default,,0000,0000,0000,,but where does it say it in here Dialogue: 0,0:10:05.14,0:10:08.36,Default,,0000,0000,0000,,here we created the testable trip service Dialogue: 0,0:10:08.36,0:10:11.23,Default,,0000,0000,0000,,we invoke a method, pass null, throws an exception Dialogue: 0,0:10:11.23,0:10:14.61,Default,,0000,0000,0000,,but where's the user not logged in? Dialogue: 0,0:10:16.78,0:10:18.64,Default,,0000,0000,0000,,it's here, it's hidden Dialogue: 0,0:10:18.82,0:10:21.35,Default,,0000,0000,0000,,so we need to fix that Dialogue: 0,0:10:21.35,0:10:23.59,Default,,0000,0000,0000,,we need to introduce the concept Dialogue: 0,0:10:23.59,0:10:26.78,Default,,0000,0000,0000,,oh by the way, the reason that I have this weird notation in here Dialogue: 0,0:10:26.78,0:10:30.09,Default,,0000,0000,0000,,it's kind of weird for java people Dialogue: 0,0:10:30.09,0:10:32.26,Default,,0000,0000,0000,,but normally the Ruby they use this convention Dialogue: 0,0:10:32.26,0:10:34.19,Default,,0000,0000,0000,,because I can just collapse the method Dialogue: 0,0:10:34.19,0:10:38.55,Default,,0000,0000,0000,,and then I have the specification of my class Dialogue: 0,0:10:38.55,0:10:40.10,Default,,0000,0000,0000,,and normally I read like Dialogue: 0,0:10:40.10,0:10:44.71,Default,,0000,0000,0000,,trip service should do something Dialogue: 0,0:10:44.71,0:10:49.63,Default,,0000,0000,0000,,so that's how I normally prefer to create my test Dialogue: 0,0:10:50.35,0:10:55.96,Default,,0000,0000,0000,,so this is all about the logged in user that is not there anywhere Dialogue: 0,0:10:55.96,0:10:57.50,Default,,0000,0000,0000,,so I'm gonna create it Dialogue: 0,0:10:58.98,0:11:06.36,Default,,0000,0000,0000,,logged in user is null Dialogue: 0,0:11:07.82,0:11:09.86,Default,,0000,0000,0000,,so now I'm gonna create this guy Dialogue: 0,0:11:09.86,0:11:15.65,Default,,0000,0000,0000,,create field user logged in user Dialogue: 0,0:11:18.21,0:11:23.33,Default,,0000,0000,0000,,and I'm gonna say logged in user Dialogue: 0,0:11:24.14,0:11:28.65,Default,,0000,0000,0000,,so now it is little bit better because I introduced the concept that I was talking about Dialogue: 0,0:11:31.60,0:11:35.38,Default,,0000,0000,0000,,I don't like the nulls Dialogue: 0,0:11:35.38,0:11:39.43,Default,,0000,0000,0000,,cause null doesn't mean much in this case Dialogue: 0,0:11:39.43,0:11:51.01,Default,,0000,0000,0000,,so let's say logged in user is not logged in Dialogue: 0,0:11:51.01,0:11:55.11,Default,,0000,0000,0000,,or in fact in a web application Dialogue: 0,0:11:56.61,0:12:01.14,Default,,0000,0000,0000,,the opposite of logged in user is normally a guest Dialogue: 0,0:12:01.14,0:12:06.42,Default,,0000,0000,0000,,so here we take the opportunity start using the concepts that Dialogue: 0,0:12:06.42,0:12:10.64,Default,,0000,0000,0000,,you probably gonna speak the behavior to business people Dialogue: 0,0:12:10.64,0:12:14.40,Default,,0000,0000,0000,,right, so it started to use your domain language Dialogue: 0,0:12:15.38,0:12:22.43,Default,,0000,0000,0000,,in here, I have the user that should be friends with or not Dialogue: 0,0:12:22.55,0:12:25.93,Default,,0000,0000,0000,,in this case, I prefer to make it explicit that is Dialogue: 0,0:12:28.26,0:12:30.60,Default,,0000,0000,0000,,unused user Dialogue: 0,0:12:39.76,0:12:45.39,Default,,0000,0000,0000,,so now, see if I can Dialogue: 0,0:12:45.71,0:12:52.95,Default,,0000,0000,0000,,I'm just trying to see if I can make my Infinitest be happy Dialogue: 0,0:12:53.86,0:12:54.80,Default,,0000,0000,0000,,but it's not Dialogue: 0,0:12:54.80,0:12:58.16,Default,,0000,0000,0000,,so I won't be trusting my Infinitest unfortunately Dialogue: 0,0:13:02.38,0:13:04.71,Default,,0000,0000,0000,,so I much happier with my test now Dialogue: 0,0:13:04.71,0:13:08.32,Default,,0000,0000,0000,,and by the way my Infinitest is working again Dialogue: 0,0:13:09.03,0:13:11.76,Default,,0000,0000,0000,,so now my test reflex what I was talking about Dialogue: 0,0:13:11.76,0:13:14.52,Default,,0000,0000,0000,,so should throw an exception when user is not logged in Dialogue: 0,0:13:14.52,0:13:16.91,Default,,0000,0000,0000,,so the logged in user is a guest Dialogue: 0,0:13:16.91,0:13:18.76,Default,,0000,0000,0000,,and then throws an exception Dialogue: 0,0:13:18.76,0:13:19.79,Default,,0000,0000,0000,,so awesome Dialogue: 0,0:13:19.79,0:13:21.52,Default,,0000,0000,0000,,so what we can do right now is Dialogue: 0,0:13:21.52,0:13:23.42,Default,,0000,0000,0000,,rerun the code coverage Dialogue: 0,0:13:30.31,0:13:32.45,Default,,0000,0000,0000,,I just want to run the junit first Dialogue: 0,0:13:32.45,0:13:34.00,Default,,0000,0000,0000,,just to make it sure Dialogue: 0,0:13:34.00,0:13:34.72,Default,,0000,0000,0000,,cool Dialogue: 0,0:13:34.77,0:13:37.31,Default,,0000,0000,0000,,now I can run my code coverage Dialogue: 0,0:13:43.25,0:13:45.43,Default,,0000,0000,0000,,so now what I do is Dialogue: 0,0:13:45.46,0:13:46.70,Default,,0000,0000,0000,,according to my code coverage Dialogue: 0,0:13:46.70,0:13:50.70,Default,,0000,0000,0000,,I can easily see what is the second shortest branch Dialogue: 0,0:13:51.70,0:13:56.26,Default,,0000,0000,0000,,so basically, now is this for loop in here Dialogue: 0,0:13:57.40,0:14:00.24,Default,,0000,0000,0000,,and then I say if it's friend Dialogue: 0,0:14:00.24,0:14:02.41,Default,,0000,0000,0000,,so this is the deepest Dialogue: 0,0:14:02.41,0:14:05.57,Default,,0000,0000,0000,,cause to get to here this flag needs to be true Dialogue: 0,0:14:05.63,0:14:10.19,Default,,0000,0000,0000,,so basically what I need now is when the user is logged in Dialogue: 0,0:14:10.19,0:14:14.37,Default,,0000,0000,0000,,but he's not friends with the user passed as parameter Dialogue: 0,0:14:15.16,0:14:19.71,Default,,0000,0000,0000,,so we're gonna write the test for that Dialogue: 0,0:14:19.71,0:14:25.54,Default,,0000,0000,0000,,so let's keep the code coverage on Dialogue: 0,0:14:27.84,0:14:31.70,Default,,0000,0000,0000,,so let's say Dialogue: 0,0:14:34.48,0:14:48.45,Default,,0000,0000,0000,,should not return any trips when users are not friends, right? Dialogue: 0,0:14:48.45,0:14:54.44,Default,,0000,0000,0000,,so I'm gonna borrow these guys here for seconds Dialogue: 0,0:14:57.22,0:15:00.08,Default,,0000,0000,0000,,so now I need a logged in user Dialogue: 0,0:15:00.08,0:15:03.91,Default,,0000,0000,0000,,so I say, a registered user Dialogue: 0,0:15:05.06,0:15:06.63,Default,,0000,0000,0000,,let's create this guy Dialogue: 0,0:15:14.09,0:15:23.96,Default,,0000,0000,0000,,and here what I would need is a list trip trips Dialogue: 0,0:15:24.17,0:15:29.73,Default,,0000,0000,0000,,let's call it friend trips Dialogue: 0,0:15:30.46,0:15:32.11,Default,,0000,0000,0000,,so import all that Dialogue: 0,0:15:42.97,0:15:44.70,Default,,0000,0000,0000,,so basically what I need now Dialogue: 0,0:15:44.70,0:15:45.94,Default,,0000,0000,0000,,I need a proper user Dialogue: 0,0:15:45.94,0:15:48.72,Default,,0000,0000,0000,,I can't have a user in here Dialogue: 0,0:15:49.08,0:15:51.32,Default,,0000,0000,0000,,so I'll call it a Dialogue: 0,0:15:51.73,0:15:55.13,Default,,0000,0000,0000,,let's call it friend Dialogue: 0,0:15:56.10,0:16:00.20,Default,,0000,0000,0000,,so I need a user that is friend Dialogue: 0,0:16:04.06,0:16:11.36,Default,,0000,0000,0000,,so add friend, another user Dialogue: 0,0:16:13.66,0:16:18.70,Default,,0000,0000,0000,,friend, let's say add trip to brazil Dialogue: 0,0:16:22.38,0:16:25.18,Default,,0000,0000,0000,,so let's create these guys Dialogue: 0,0:16:41.42,0:16:44.55,Default,,0000,0000,0000,,ans so now I have a friend Dialogue: 0,0:16:44.93,0:16:48.57,Default,,0000,0000,0000,,that is friend with another user that has a trip to brazil Dialogue: 0,0:16:49.05,0:16:52.62,Default,,0000,0000,0000,,I have a logged in user that is a valid user Dialogue: 0,0:16:53.41,0:16:55.87,Default,,0000,0000,0000,,but they're not friends Dialogue: 0,0:16:55.87,0:17:01.96,Default,,0000,0000,0000,,so I need to assert that Dialogue: 0,0:17:03.66,0:17:08.52,Default,,0000,0000,0000,,friend trip dot size is zero Dialogue: 0,0:17:10.90,0:17:13.69,Default,,0000,0000,0000,,right, I could have said Dialogue: 0,0:17:13.69,0:17:16.29,Default,,0000,0000,0000,,assert that is empty doesn't matter Dialogue: 0,0:17:16.29,0:17:20.24,Default,,0000,0000,0000,,so my Infinitest that apparently is working Dialogue: 0,0:17:20.32,0:17:24.100,Default,,0000,0000,0000,,just confirm running the JUnit command Dialogue: 0,0:17:25.14,0:17:27.42,Default,,0000,0000,0000,,so it saying that it is green Dialogue: 0,0:17:27.42,0:17:29.73,Default,,0000,0000,0000,,that happens quite often in legacy code Dialogue: 0,0:17:29.73,0:17:30.98,Default,,0000,0000,0000,,cause the code is already there Dialogue: 0,0:17:30.98,0:17:33.40,Default,,0000,0000,0000,,you just making sure that you understand what code does Dialogue: 0,0:17:33.40,0:17:34.62,Default,,0000,0000,0000,,so that's quite common Dialogue: 0,0:17:34.62,0:17:37.48,Default,,0000,0000,0000,,I'm just run the code coverage Dialogue: 0,0:17:37.51,0:17:40.78,Default,,0000,0000,0000,,so running the code coverage now we progressed little bit Dialogue: 0,0:17:40.78,0:17:44.56,Default,,0000,0000,0000,,so as you can see my new test now moved forward Dialogue: 0,0:17:44.56,0:17:46.16,Default,,0000,0000,0000,,so went for the shortest branch Dialogue: 0,0:17:46.16,0:17:49.28,Default,,0000,0000,0000,,where the user was logged in Dialogue: 0,0:17:49.28,0:17:50.95,Default,,0000,0000,0000,,but they were not friends Dialogue: 0,0:17:52.32,0:17:56.64,Default,,0000,0000,0000,,so it was returning always false and then that it Dialogue: 0,0:17:57.20,0:17:59.31,Default,,0000,0000,0000,,so we're not done yet Dialogue: 0,0:17:59.31,0:18:02.31,Default,,0000,0000,0000,,because now we need to do some refactoring here Dialogue: 0,0:18:02.31,0:18:04.47,Default,,0000,0000,0000,,there is some duplication Dialogue: 0,0:18:04.47,0:18:06.30,Default,,0000,0000,0000,,so let's get rid of it Dialogue: 0,0:18:07.09,0:18:10.78,Default,,0000,0000,0000,,so let's put a before method Dialogue: 0,0:18:12.56,0:18:15.42,Default,,0000,0000,0000,,let's transform this guy Dialogue: 0,0:18:15.42,0:18:18.61,Default,,0000,0000,0000,,local variable into field Dialogue: 0,0:18:18.64,0:18:20.69,Default,,0000,0000,0000,,it's great Dialogue: 0,0:18:20.69,0:18:22.24,Default,,0000,0000,0000,,it's awsome Dialogue: 0,0:18:24.57,0:18:26.60,Default,,0000,0000,0000,,now we can move this guy up Dialogue: 0,0:18:35.80,0:18:37.17,Default,,0000,0000,0000,,right Dialogue: 0,0:18:38.29,0:18:44.05,Default,,0000,0000,0000,,so now I can go to the deepest branch Dialogue: 0,0:18:44.07,0:18:45.67,Default,,0000,0000,0000,,so now what I need is Dialogue: 0,0:18:45.67,0:18:51.57,Default,,0000,0000,0000,,when the logged in user is friends with the user passed as parameter Dialogue: 0,0:18:52.94,0:18:56.17,Default,,0000,0000,0000,,then I need the trips, return the trips Dialogue: 0,0:18:59.86,0:19:07.71,Default,,0000,0000,0000,,should return friend trips when users are friends Dialogue: 0,0:19:08.74,0:19:11.07,Default,,0000,0000,0000,,right? so that's the one we testing Dialogue: 0,0:19:11.07,0:19:13.59,Default,,0000,0000,0000,,so I'm gonna borrow this again Dialogue: 0,0:19:22.72,0:19:24.97,Default,,0000,0000,0000,,so you shouldn't do copy and pate Dialogue: 0,0:19:24.97,0:19:26.97,Default,,0000,0000,0000,,I don't do copy and paste Dialogue: 0,0:19:26.100,0:19:29.32,Default,,0000,0000,0000,,what you saw was an illusion Dialogue: 0,0:19:29.32,0:19:33.28,Default,,0000,0000,0000,,so I never, never ever do copy and paste Dialogue: 0,0:19:34.44,0:19:37.80,Default,,0000,0000,0000,,so in this case here what I want you to do now is Dialogue: 0,0:19:38.66,0:19:45.83,Default,,0000,0000,0000,,friend, add friend with logged in user Dialogue: 0,0:19:46.81,0:19:49.18,Default,,0000,0000,0000,,let's add another trip Dialogue: 0,0:20:03.43,0:20:08.22,Default,,0000,0000,0000,,so now of course that I expect my Infinitest are red saying with this Dialogue: 0,0:20:08.22,0:20:11.52,Default,,0000,0000,0000,,red, of course I expect this should be true Dialogue: 0,0:20:11.52,0:20:13.91,Default,,0000,0000,0000,,because now the users are friends Dialogue: 0,0:20:13.91,0:20:14.78,Default,,0000,0000,0000,,and if I save Dialogue: 0,0:20:14.78,0:20:18.51,Default,,0000,0000,0000,,it still saying that it's red Dialogue: 0,0:20:18.51,0:20:21.70,Default,,0000,0000,0000,,so let's run junit by hand Dialogue: 0,0:20:21.70,0:20:25.28,Default,,0000,0000,0000,,oops, I keep getting the shortcuts wrong Dialogue: 0,0:20:25.28,0:20:27.62,Default,,0000,0000,0000,,because I kept using windows Dialogue: 0,0:20:27.62,0:20:32.59,Default,,0000,0000,0000,,my mac and intellij keep getting (???) Dialogue: 0,0:20:32.59,0:20:37.13,Default,,0000,0000,0000,,so what it's saying is, because now what's happening Dialogue: 0,0:20:37.91,0:20:39.37,Default,,0000,0000,0000,,just restore this screen Dialogue: 0,0:20:40.27,0:20:41.82,Default,,0000,0000,0000,,what's happening is Dialogue: 0,0:20:41.82,0:20:47.42,Default,,0000,0000,0000,,the code is now getting here in the trip dao Dialogue: 0,0:20:47.42,0:20:49.39,Default,,0000,0000,0000,,that is a statical Dialogue: 0,0:20:49.55,0:20:53.21,Default,,0000,0000,0000,,and as soon as the code execute this guy Dialogue: 0,0:20:53.21,0:20:55.03,Default,,0000,0000,0000,,then there's an exception being thrown Dialogue: 0,0:20:55.03,0:20:56.74,Default,,0000,0000,0000,,now I give the same thing Dialogue: 0,0:20:56.74,0:20:59.61,Default,,0000,0000,0000,,so this is just to prove the point that Dialogue: 0,0:20:59.61,0:21:01.08,Default,,0000,0000,0000,,just to make a point Dialogue: 0,0:21:01.08,0:21:06.52,Default,,0000,0000,0000,,that we shouldn't ever be calling or execute another class in a unit test Dialogue: 0,0:21:06.52,0:21:13.06,Default,,0000,0000,0000,,because this, in the real world, would be going to the database and fetching data blah blah blah Dialogue: 0,0:21:12.72,0:21:17.16,Default,,0000,0000,0000,,the test for my trip service shouldn't care about that Dialogue: 0,0:21:17.16,0:21:21.53,Default,,0000,0000,0000,,so we need to do exactly the same thing Dialogue: 0,0:21:21.53,0:21:25.17,Default,,0000,0000,0000,,that we've done for user session Dialogue: 0,0:21:25.17,0:21:29.62,Default,,0000,0000,0000,,so you can break the hard wired dependencies Dialogue: 0,0:21:29.62,0:21:32.98,Default,,0000,0000,0000,,like singleton and staticals Dialogue: 0,0:21:32.98,0:21:36.95,Default,,0000,0000,0000,,or objects being created inside method is exactly the same Dialogue: 0,0:21:36.95,0:21:39.17,Default,,0000,0000,0000,,so basically what we do Dialogue: 0,0:21:39.98,0:21:41.58,Default,,0000,0000,0000,,create a method Dialogue: 0,0:21:42.49,0:21:48.77,Default,,0000,0000,0000,,let's say trips by user Dialogue: 0,0:21:48.77,0:21:51.29,Default,,0000,0000,0000,,that is also protected Dialogue: 0,0:21:51.29,0:21:56.30,Default,,0000,0000,0000,,and then we go back to our tests Dialogue: 0,0:22:02.09,0:22:04.41,Default,,0000,0000,0000,,we'll do the same thing Dialogue: 0,0:22:17.11,0:22:19.84,Default,,0000,0000,0000,,so basically what we'll do Dialogue: 0,0:22:20.14,0:22:22.32,Default,,0000,0000,0000,,we will just return Dialogue: 0,0:22:22.32,0:22:23.67,Default,,0000,0000,0000,,so we will receive the user Dialogue: 0,0:22:23.67,0:22:26.78,Default,,0000,0000,0000,,the user in our test that has two trips Dialogue: 0,0:22:29.28,0:22:32.48,Default,,0000,0000,0000,,so basically we just return that Dialogue: 0,0:22:32.48,0:22:35.15,Default,,0000,0000,0000,,the user dot trips Dialogue: 0,0:22:36.45,0:22:39.08,Default,,0000,0000,0000,,so as soon as do that my test is green Dialogue: 0,0:22:40.05,0:22:43.95,Default,,0000,0000,0000,,so if I run my code coverage Dialogue: 0,0:22:43.95,0:22:45.10,Default,,0000,0000,0000,,awesome Dialogue: 0,0:22:45.10,0:22:51.07,Default,,0000,0000,0000,,cause now I have all my existing code base Dialogue: 0,0:22:51.07,0:22:53.74,Default,,0000,0000,0000,,tested to almost 100% Dialogue: 0,0:22:53.74,0:22:59.96,Default,,0000,0000,0000,,of course that you might say that I created are not test because I overriding them Dialogue: 0,0:22:59.96,0:23:02.40,Default,,0000,0000,0000,,but that's alright because that's just my seam Dialogue: 0,0:23:02.40,0:23:04.88,Default,,0000,0000,0000,,that's a very thin layer to delegate Dialogue: 0,0:23:04.88,0:23:07.45,Default,,0000,0000,0000,,and that's intermediatary stage anyway Dialogue: 0,0:23:07.45,0:23:11.68,Default,,0000,0000,0000,,so now few clean ups that we can do Dialogue: 0,0:23:11.68,0:23:13.37,Default,,0000,0000,0000,,normally what I do is Dialogue: 0,0:23:13.37,0:23:19.13,Default,,0000,0000,0000,,because this guy is here and is here Dialogue: 0,0:23:19.13,0:23:24.100,Default,,0000,0000,0000,,and the only situation that I don't want it should be like that is this one Dialogue: 0,0:23:24.100,0:23:26.46,Default,,0000,0000,0000,,so I leave this one Dialogue: 0,0:23:26.46,0:23:28.37,Default,,0000,0000,0000,,and I just move this one out Dialogue: 0,0:23:29.60,0:23:31.71,Default,,0000,0000,0000,,because then it is common to all other tests Dialogue: 0,0:23:31.71,0:23:37.28,Default,,0000,0000,0000,,all other tests that I want the logged in user should be a valid one Dialogue: 0,0:23:37.31,0:23:40.04,Default,,0000,0000,0000,,so once I do that Dialogue: 0,0:23:40.09,0:23:41.88,Default,,0000,0000,0000,,if I save Dialogue: 0,0:23:41.88,0:23:44.33,Default,,0000,0000,0000,,then if I just make it sure Dialogue: 0,0:23:44.33,0:23:46.44,Default,,0000,0000,0000,,so all my tests are green Dialogue: 0,0:23:46.44,0:23:47.53,Default,,0000,0000,0000,,and that's great Dialogue: 0,0:23:47.53,0:23:52.05,Default,,0000,0000,0000,,so for the first part, it's great we're done Dialogue: 0,0:23:52.05,0:23:56.47,Default,,0000,0000,0000,,now our code is tested and we're free to start refactoring Dialogue: 0,0:23:57.45,0:24:02.49,Default,,0000,0000,0000,,so now that we're in a very good point to commit Dialogue: 0,0:24:02.49,0:24:06.11,Default,,0000,0000,0000,,so git status Dialogue: 0,0:24:06.11,0:24:08.44,Default,,0000,0000,0000,,git commit Dialogue: 0,0:24:08.44,0:24:17.76,Default,,0000,0000,0000,,unit tests for trip service Dialogue: 0,0:24:17.76,0:24:19.61,Default,,0000,0000,0000,,cool, awesome Dialogue: 0,0:24:23.66,0:24:26.11,Default,,0000,0000,0000,,look at this test, the problem is Dialogue: 0,0:24:26.11,0:24:29.59,Default,,0000,0000,0000,,legacy code is that quite often you need Dialogue: 0,0:24:29.59,0:24:32.43,Default,,0000,0000,0000,,this is of course very simple one Dialogue: 0,0:24:33.22,0:24:39.40,Default,,0000,0000,0000,,but imagine like a same method with hundreds of line Dialogue: 0,0:24:39.40,0:24:42.11,Default,,0000,0000,0000,,and here we're just talking about one object being created Dialogue: 0,0:24:42.11,0:24:43.43,Default,,0000,0000,0000,,to pass in as parameter Dialogue: 0,0:24:43.43,0:24:48.04,Default,,0000,0000,0000,,but quite often what we do is we need to create this massive object graph Dialogue: 0,0:24:48.04,0:24:50.06,Default,,0000,0000,0000,,to pass in as parameter Dialogue: 0,0:24:50.06,0:24:53.02,Default,,0000,0000,0000,,so we can reach all the branches and stuff Dialogue: 0,0:24:53.02,0:24:55.16,Default,,0000,0000,0000,,so we can start cleaning that up Dialogue: 0,0:24:55.16,0:24:58.11,Default,,0000,0000,0000,,cause I don't like all these duplication in here and here Dialogue: 0,0:24:58.11,0:25:01.89,Default,,0000,0000,0000,,so the way that I would love to see it Dialogue: 0,0:25:01.89,0:25:03.71,Default,,0000,0000,0000,,is using a builder Dialogue: 0,0:25:03.71,0:25:09.02,Default,,0000,0000,0000,,so basically what I loved to see is something like that Dialogue: 0,0:25:09.02,0:25:11.67,Default,,0000,0000,0000,,user friend Dialogue: 0,0:25:12.11,0:25:18.76,Default,,0000,0000,0000,,kind of like a friend or a user Dialogue: 0,0:25:23.51,0:25:35.24,Default,,0000,0000,0000,,friends with another user and logged in user Dialogue: 0,0:25:35.92,0:25:45.61,Default,,0000,0000,0000,,with trips to brazil and to london Dialogue: 0,0:25:46.76,0:25:49.86,Default,,0000,0000,0000,,so that's the sort of stuff that I would like to see Dialogue: 0,0:25:50.47,0:25:51.84,Default,,0000,0000,0000,,I think I read far better Dialogue: 0,0:25:51.84,0:25:54.76,Default,,0000,0000,0000,,so let's try to see if we can make that happen Dialogue: 0,0:25:55.13,0:25:57.72,Default,,0000,0000,0000,,so let's put a build method in here Dialogue: 0,0:25:58.09,0:26:00.34,Default,,0000,0000,0000,,let's use the builder pattern for that Dialogue: 0,0:26:01.59,0:26:05.40,Default,,0000,0000,0000,,let's say user builder Dialogue: 0,0:26:06.67,0:26:11.96,Default,,0000,0000,0000,,so that would be what I want to see Dialogue: 0,0:26:11.96,0:26:15.66,Default,,0000,0000,0000,,so I will gonna comment this out a little bit Dialogue: 0,0:26:16.82,0:26:24.64,Default,,0000,0000,0000,,so I'll say, public, static Dialogue: 0,0:26:25.44,0:26:27.98,Default,,0000,0000,0000,,class, user builder Dialogue: 0,0:26:30.88,0:26:34.20,Default,,0000,0000,0000,,let's start creating this method in there Dialogue: 0,0:26:47.52,0:26:49.96,Default,,0000,0000,0000,,the way that you can chain methods Dialogue: 0,0:26:49.96,0:26:52.98,Default,,0000,0000,0000,,you'll just keep returning the same object Dialogue: 0,0:26:52.98,0:26:55.19,Default,,0000,0000,0000,,and then you can chain all the methods Dialogue: 0,0:26:55.19,0:26:57.38,Default,,0000,0000,0000,,so let's create the use builder Dialogue: 0,0:27:00.66,0:27:04.96,Default,,0000,0000,0000,,so now we just create the next method Dialogue: 0,0:27:07.54,0:27:09.56,Default,,0000,0000,0000,,keep returning the user builder Dialogue: 0,0:27:09.75,0:27:15.45,Default,,0000,0000,0000,,so here we're passing two users Dialogue: 0,0:27:17.04,0:27:21.74,Default,,0000,0000,0000,,as I always said, there are just three numbers in programming Dialogue: 0,0:27:21.74,0:27:24.44,Default,,0000,0000,0000,,there is 0, there is 1 and there is many Dialogue: 0,0:27:24.44,0:27:26.72,Default,,0000,0000,0000,,there's nothing more than that Dialogue: 0,0:27:26.79,0:27:29.59,Default,,0000,0000,0000,,so let's make it many Dialogue: 0,0:27:31.27,0:27:33.30,Default,,0000,0000,0000,,so let's use variable arguments Dialogue: 0,0:27:33.30,0:27:36.80,Default,,0000,0000,0000,,cause that I can pass many users as I want Dialogue: 0,0:27:38.11,0:27:41.32,Default,,0000,0000,0000,,so let's put friends Dialogue: 0,0:27:43.21,0:27:47.77,Default,,0000,0000,0000,,let's say these friends equals friends Dialogue: 0,0:27:48.04,0:27:50.62,Default,,0000,0000,0000,,let's keep returning same objects Dialogue: 0,0:27:50.62,0:27:52.89,Default,,0000,0000,0000,,let's create this guy Dialogue: 0,0:27:53.01,0:27:57.61,Default,,0000,0000,0000,,should never leave arrays uninitialized Dialogue: 0,0:27:57.61,0:28:01.09,Default,,0000,0000,0000,,so new user Dialogue: 0,0:28:05.40,0:28:07.86,Default,,0000,0000,0000,,avoid some null pointer exception Dialogue: 0,0:28:08.66,0:28:16.28,Default,,0000,0000,0000,,so great, let's go for our second method Dialogue: 0,0:28:16.36,0:28:18.82,Default,,0000,0000,0000,,so user builder Dialogue: 0,0:28:18.82,0:28:21.54,Default,,0000,0000,0000,,let's do the same thing Dialogue: 0,0:28:21.54,0:28:28.13,Default,,0000,0000,0000,,because then we're free to use our method to pass as many trips as we want Dialogue: 0,0:28:37.01,0:28:39.21,Default,,0000,0000,0000,,let's return trips Dialogue: 0,0:28:39.21,0:28:41.02,Default,,0000,0000,0000,,let's create trips Dialogue: 0,0:28:41.02,0:28:44.89,Default,,0000,0000,0000,,normally what I do Dialogue: 0,0:28:44.89,0:28:48.70,Default,,0000,0000,0000,,I write the way I want to read it Dialogue: 0,0:28:48.84,0:28:52.12,Default,,0000,0000,0000,,and then I start creating all the code from there Dialogue: 0,0:28:52.97,0:28:56.55,Default,,0000,0000,0000,,and let's create the build method Dialogue: 0,0:28:56.55,0:29:04.28,Default,,0000,0000,0000,,so build method, I like it to be the last method Dialogue: 0,0:29:04.28,0:29:10.92,Default,,0000,0000,0000,,so the build method is the method that actually build the object Dialogue: 0,0:29:11.56,0:29:14.61,Default,,0000,0000,0000,,so new user Dialogue: 0,0:29:15.65,0:29:17.35,Default,,0000,0000,0000,,let's return the user Dialogue: 0,0:29:17.35,0:29:19.08,Default,,0000,0000,0000,,and then I say Dialogue: 0,0:29:19.66,0:29:23.18,Default,,0000,0000,0000,,add trips to user Dialogue: 0,0:29:23.22,0:29:28.89,Default,,0000,0000,0000,,add friends to user Dialogue: 0,0:29:32.05,0:29:37.88,Default,,0000,0000,0000,,it's always to cool to combine the method name and the parameter Dialogue: 0,0:29:37.88,0:29:40.70,Default,,0000,0000,0000,,it makes it much easier to read it Dialogue: 0,0:29:40.70,0:29:43.26,Default,,0000,0000,0000,,avoid duplication in names as well Dialogue: 0,0:29:43.26,0:29:45.99,Default,,0000,0000,0000,,so let's do the trips first Dialogue: 0,0:29:45.99,0:29:49.55,Default,,0000,0000,0000,,so for each Dialogue: 0,0:29:49.55,0:29:52.00,Default,,0000,0000,0000,,here we're doing the trips Dialogue: 0,0:29:52.03,0:29:56.04,Default,,0000,0000,0000,,so that's a trip that's a trip that's trips Dialogue: 0,0:29:56.24,0:30:02.67,Default,,0000,0000,0000,,so user dot add trip, trip Dialogue: 0,0:30:04.26,0:30:06.64,Default,,0000,0000,0000,,let's do the same thing for friends Dialogue: 0,0:30:06.64,0:30:08.87,Default,,0000,0000,0000,,create add friends Dialogue: 0,0:30:11.15,0:30:12.28,Default,,0000,0000,0000,,let's do Dialogue: 0,0:30:12.28,0:30:14.65,Default,,0000,0000,0000,,for each Dialogue: 0,0:30:14.65,0:30:17.04,Default,,0000,0000,0000,,so that's user Dialogue: 0,0:30:17.04,0:30:19.94,Default,,0000,0000,0000,,that's friend Dialogue: 0,0:30:19.94,0:30:21.94,Default,,0000,0000,0000,,friends Dialogue: 0,0:30:21.94,0:30:28.48,Default,,0000,0000,0000,,user dot add friend friend Dialogue: 0,0:30:28.84,0:30:30.78,Default,,0000,0000,0000,,awesome, cool Dialogue: 0,0:30:30.78,0:30:35.60,Default,,0000,0000,0000,,so now, Infinitest saying everything is green Dialogue: 0,0:30:35.64,0:30:39.76,Default,,0000,0000,0000,,so I can delete this Dialogue: 0,0:30:41.32,0:30:43.65,Default,,0000,0000,0000,,and I can replace this one as well Dialogue: 0,0:30:43.65,0:30:45.49,Default,,0000,0000,0000,,so let's replace this one Dialogue: 0,0:31:15.48,0:31:18.58,Default,,0000,0000,0000,,awsome, let's comment that out Dialogue: 0,0:31:18.68,0:31:21.94,Default,,0000,0000,0000,,so if I run everything, still green Dialogue: 0,0:31:21.94,0:31:23.62,Default,,0000,0000,0000,,again, awesome Dialogue: 0,0:31:25.10,0:31:29.76,Default,,0000,0000,0000,,so now my tests are slightly more readable Dialogue: 0,0:31:29.76,0:31:33.51,Default,,0000,0000,0000,,so what I will do move this builder out Dialogue: 0,0:31:33.51,0:31:34.98,Default,,0000,0000,0000,,so let's say Dialogue: 0,0:31:34.98,0:31:37.00,Default,,0000,0000,0000,,move type to new file Dialogue: 0,0:31:39.07,0:31:41.40,Default,,0000,0000,0000,,and basically what if you do Dialogue: 0,0:31:41.40,0:31:47.58,Default,,0000,0000,0000,,if you just move this class the same folder where the TripServiceTest is Dialogue: 0,0:31:47.58,0:31:49.48,Default,,0000,0000,0000,,for now it's good Dialogue: 0,0:31:50.34,0:31:52.15,Default,,0000,0000,0000,,so now that is out Dialogue: 0,0:31:52.15,0:31:56.41,Default,,0000,0000,0000,,static import this methods in here Dialogue: 0,0:31:56.41,0:31:59.38,Default,,0000,0000,0000,,static import this methods in here Dialogue: 0,0:31:59.38,0:32:01.100,Default,,0000,0000,0000,,so let's make code symmetric Dialogue: 0,0:32:01.100,0:32:04.92,Default,,0000,0000,0000,,so both of them are symmetric Dialogue: 0,0:32:04.92,0:32:09.43,Default,,0000,0000,0000,,and let's remove all the unutilized import Dialogue: 0,0:32:09.43,0:32:12.08,Default,,0000,0000,0000,,so there's no unused imports anywhere Dialogue: 0,0:32:12.08,0:32:13.62,Default,,0000,0000,0000,,so excellent Dialogue: 0,0:32:13.62,0:32:17.10,Default,,0000,0000,0000,,so now I'm much much happier with my test Dialogue: 0,0:32:17.10,0:32:19.72,Default,,0000,0000,0000,,because then I can read it properly Dialogue: 0,0:32:19.72,0:32:22.67,Default,,0000,0000,0000,,and that's a great point to commit as well Dialogue: 0,0:32:22.67,0:32:24.21,Default,,0000,0000,0000,,so let's see Dialogue: 0,0:32:24.29,0:32:25.92,Default,,0000,0000,0000,,we got status Dialogue: 0,0:32:25.96,0:32:28.61,Default,,0000,0000,0000,,git add Dialogue: 0,0:32:29.79,0:32:31.47,Default,,0000,0000,0000,,git commit Dialogue: 0,0:32:31.47,0:32:45.82,Default,,0000,0000,0000,,user builder created and used in trip service test Dialogue: 0,0:32:45.82,0:32:48.65,Default,,0000,0000,0000,,cool, awesome Dialogue: 0,0:32:52.82,0:32:56.24,Default,,0000,0000,0000,,so now we're finally ready to start refactoring this Dialogue: 0,0:32:56.24,0:32:58.19,Default,,0000,0000,0000,,as we're saying before Dialogue: 0,0:32:58.19,0:32:59.69,Default,,0000,0000,0000,,where was it, here Dialogue: 0,0:33:01.67,0:33:06.79,Default,,0000,0000,0000,,we normally start testing from the shortest branch to the deepest Dialogue: 0,0:33:07.65,0:33:10.46,Default,,0000,0000,0000,,and when we're doing refactoring it's the other way around Dialogue: 0,0:33:10.46,0:33:12.64,Default,,0000,0000,0000,,you start from the deepest branch Dialogue: 0,0:33:13.58,0:33:16.66,Default,,0000,0000,0000,,to the shortest delta branches Dialogue: 0,0:33:17.52,0:33:19.35,Default,,0000,0000,0000,,the reason beneath is Dialogue: 0,0:33:19.35,0:33:22.38,Default,,0000,0000,0000,,if you want to start refactoring in the middle of your code Dialogue: 0,0:33:22.38,0:33:23.95,Default,,0000,0000,0000,,you need to understand everything Dialogue: 0,0:33:23.95,0:33:25.31,Default,,0000,0000,0000,,and normally Dialogue: 0,0:33:26.52,0:33:29.76,Default,,0000,0000,0000,,legacy code, they have global variable everywhere Dialogue: 0,0:33:29.76,0:33:30.81,Default,,0000,0000,0000,,and dependencies Dialogue: 0,0:33:30.81,0:33:33.69,Default,,0000,0000,0000,,set a flag in one place, checks it on the other Dialogue: 0,0:33:33.69,0:33:36.74,Default,,0000,0000,0000,,but if you go straight to the deepest branch Dialogue: 0,0:33:36.74,0:33:39.82,Default,,0000,0000,0000,,the deepest branch doesn't depend on anything Dialogue: 0,0:33:39.82,0:33:43.25,Default,,0000,0000,0000,,it normally receives everything that it needs that is needs Dialogue: 0,0:33:43.25,0:33:45.42,Default,,0000,0000,0000,,and then it does something with it Dialogue: 0,0:33:45.42,0:33:48.49,Default,,0000,0000,0000,,if you're able to extract that Dialogue: 0,0:33:48.49,0:33:52.51,Default,,0000,0000,0000,,refactor that the deepest branch from deepest to shortest Dialogue: 0,0:33:52.51,0:33:54.00,Default,,0000,0000,0000,,you're code is start shrinking Dialogue: 0,0:33:54.00,0:33:56.95,Default,,0000,0000,0000,,so let's look at the code Dialogue: 0,0:33:56.95,0:33:59.73,Default,,0000,0000,0000,,so the deepest branch of the code Dialogue: 0,0:33:59.73,0:34:01.75,Default,,0000,0000,0000,,as we discussed before is this one Dialogue: 0,0:34:01.75,0:34:04.90,Default,,0000,0000,0000,,so to get to here Dialogue: 0,0:34:04.90,0:34:06.55,Default,,0000,0000,0000,,I need this flag to be set Dialogue: 0,0:34:06.55,0:34:08.68,Default,,0000,0000,0000,,the flag is set here Dialogue: 0,0:34:08.68,0:34:11.57,Default,,0000,0000,0000,,the problem in this example in specific Dialogue: 0,0:34:11.57,0:34:13.95,Default,,0000,0000,0000,,the deepest branch that is this line Dialogue: 0,0:34:13.95,0:34:15.26,Default,,0000,0000,0000,,doesn't do much Dialogue: 0,0:34:15.26,0:34:18.33,Default,,0000,0000,0000,,it just delegates to this one Dialogue: 0,0:34:18.33,0:34:21.36,Default,,0000,0000,0000,,so I can re-do anything with one line Dialogue: 0,0:34:21.36,0:34:24.68,Default,,0000,0000,0000,,so the second deepest branch is this one Dialogue: 0,0:34:26.40,0:34:27.94,Default,,0000,0000,0000,,right it is this bit in here Dialogue: 0,0:34:27.94,0:34:30.46,Default,,0000,0000,0000,,so let's go for this one Dialogue: 0,0:34:31.75,0:34:34.12,Default,,0000,0000,0000,,one thing that is very very important Dialogue: 0,0:34:34.12,0:34:36.19,Default,,0000,0000,0000,,when working with legacy code Dialogue: 0,0:34:36.19,0:34:41.46,Default,,0000,0000,0000,,is to understand why the method is so big Dialogue: 0,0:34:41.46,0:34:44.14,Default,,0000,0000,0000,,why is it so complicated? Dialogue: 0,0:34:44.14,0:34:50.62,Default,,0000,0000,0000,,and normally it is because the method, of course, does too much Dialogue: 0,0:34:50.62,0:34:52.90,Default,,0000,0000,0000,,that's why it has so many lines Dialogue: 0,0:34:52.90,0:34:58.33,Default,,0000,0000,0000,,so it's important that instead of us trying to make the algorithm better Dialogue: 0,0:34:58.33,0:35:01.17,Default,,0000,0000,0000,,or extract method in here Dialogue: 0,0:35:01.17,0:35:02.79,Default,,0000,0000,0000,,we should ask ourselves Dialogue: 0,0:35:02.79,0:35:04.78,Default,,0000,0000,0000,,does this responsibility Dialogue: 0,0:35:04.78,0:35:07.90,Default,,0000,0000,0000,,does this behavior belong here? Dialogue: 0,0:35:07.90,0:35:10.59,Default,,0000,0000,0000,,in this case, look at this Dialogue: 0,0:35:12.93,0:35:14.46,Default,,0000,0000,0000,,if you look at this block Dialogue: 0,0:35:14.46,0:35:23.86,Default,,0000,0000,0000,,so we go to the user object and asks for the friends Dialogue: 0,0:35:23.86,0:35:27.100,Default,,0000,0000,0000,,so we get a list of friends out of the user object Dialogue: 0,0:35:28.00,0:35:29.73,Default,,0000,0000,0000,,we iterate through it Dialogue: 0,0:35:29.73,0:35:34.24,Default,,0000,0000,0000,,just to ask if the logged user is inside that collection or not Dialogue: 0,0:35:34.24,0:35:36.42,Default,,0000,0000,0000,,so this is called feature envy Dialogue: 0,0:35:36.42,0:35:40.03,Default,,0000,0000,0000,,it's kind of the trip serivce envies the user Dialogue: 0,0:35:40.15,0:35:42.28,Default,,0000,0000,0000,,it wants to be the user class Dialogue: 0,0:35:42.28,0:35:47.76,Default,,0000,0000,0000,,so what we could do here, we need to solve the feature envy Dialogue: 0,0:35:47.76,0:35:52.85,Default,,0000,0000,0000,,if the user class has the collection of friends Dialogue: 0,0:35:52.85,0:35:55.21,Default,,0000,0000,0000,,we should ask the user class, like Dialogue: 0,0:35:55.21,0:35:58.85,Default,,0000,0000,0000,,user are you friends with this guy? Dialogue: 0,0:35:58.85,0:36:03.44,Default,,0000,0000,0000,,so, let's try to move this behavior there Dialogue: 0,0:36:03.44,0:36:04.62,Default,,0000,0000,0000,,so the first thing is Dialogue: 0,0:36:04.62,0:36:06.77,Default,,0000,0000,0000,,let's look at the user class Dialogue: 0,0:36:06.77,0:36:08.90,Default,,0000,0000,0000,,where's my user? Dialogue: 0,0:36:10.22,0:36:12.89,Default,,0000,0000,0000,,so let's close this too Dialogue: 0,0:36:12.99,0:36:15.26,Default,,0000,0000,0000,,so that's my user class Dialogue: 0,0:36:16.62,0:36:18.72,Default,,0000,0000,0000,,let's create a test for it Dialogue: 0,0:36:18.72,0:36:24.38,Default,,0000,0000,0000,,so my user class is here Dialogue: 0,0:36:24.38,0:36:30.38,Default,,0000,0000,0000,,new class, let's say user test Dialogue: 0,0:36:30.38,0:36:34.92,Default,,0000,0000,0000,,but I'm gonna put that in the test package of course Dialogue: 0,0:36:36.42,0:36:40.10,Default,,0000,0000,0000,,so that will create my user test in here Dialogue: 0,0:36:40.10,0:36:43.56,Default,,0000,0000,0000,,let's move my test here Dialogue: 0,0:36:43.56,0:36:46.81,Default,,0000,0000,0000,,cool, so what do I want? Dialogue: 0,0:36:46.81,0:36:53.38,Default,,0000,0000,0000,,I want this behavior here should be in this class Dialogue: 0,0:36:53.38,0:36:55.44,Default,,0000,0000,0000,,I want to go to the user and say, Dialogue: 0,0:36:55.44,0:36:58.19,Default,,0000,0000,0000,,"Are you friends with another user?" Dialogue: 0,0:36:58.19,0:36:59.07,Default,,0000,0000,0000,,right? Dialogue: 0,0:36:59.07,0:37:02.50,Default,,0000,0000,0000,,so, I'm gonna write this test Dialogue: 0,0:37:05.64,0:37:11.45,Default,,0000,0000,0000,,should inform when users are not friends Dialogue: 0,0:37:11.45,0:37:12.84,Default,,0000,0000,0000,,I'm gonna start with not friends Dialogue: 0,0:37:12.84,0:37:15.15,Default,,0000,0000,0000,,because it is the easiest test that I can write Dialogue: 0,0:37:15.15,0:37:16.52,Default,,0000,0000,0000,,this is the simplest one Dialogue: 0,0:37:18.88,0:37:22.34,Default,,0000,0000,0000,,here I can use my builder Dialogue: 0,0:37:22.34,0:37:34.84,Default,,0000,0000,0000,,user builder dot a user Dialogue: 0,0:37:35.05,0:37:44.51,Default,,0000,0000,0000,,so let's say that this guy is friends with Bob Dialogue: 0,0:37:44.51,0:37:49.08,Default,,0000,0000,0000,,right? let's do that Dialogue: 0,0:37:50.14,0:37:54.42,Default,,0000,0000,0000,,and then in my test, I'm gonna say Dialogue: 0,0:37:55.28,0:38:13.38,Default,,0000,0000,0000,,assert that user is friends with Paul is false Dialogue: 0,0:38:14.86,0:38:20.71,Default,,0000,0000,0000,,so basically I want to create a user that is friend with Bob Dialogue: 0,0:38:20.71,0:38:24.53,Default,,0000,0000,0000,,and of course if I ask this user if he's friend with Paul Dialogue: 0,0:38:24.53,0:38:26.27,Default,,0000,0000,0000,,it should be false Dialogue: 0,0:38:26.27,0:38:29.66,Default,,0000,0000,0000,,so let's create Bob and Paul Dialogue: 0,0:38:38.12,0:38:39.69,Default,,0000,0000,0000,,let's create Paul as well Dialogue: 0,0:38:49.25,0:38:53.43,Default,,0000,0000,0000,,so now that's the method that I want the user class have Dialogue: 0,0:38:53.43,0:38:55.24,Default,,0000,0000,0000,,let's create it Dialogue: 0,0:39:00.19,0:39:06.50,Default,,0000,0000,0000,,and of course the minimum behavior that I can have to satisfy the test Dialogue: 0,0:39:06.50,0:39:07.88,Default,,0000,0000,0000,,is false Dialogue: 0,0:39:07.88,0:39:10.41,Default,,0000,0000,0000,,so as soon as I save the false Dialogue: 0,0:39:10.41,0:39:15.24,Default,,0000,0000,0000,,my Infinitest tells me that it's passing Dialogue: 0,0:39:15.24,0:39:16.46,Default,,0000,0000,0000,,that's awesome, great Dialogue: 0,0:39:16.78,0:39:23.27,Default,,0000,0000,0000,,so let's do the other case, when the users are friends Dialogue: 0,0:39:23.27,0:39:34.91,Default,,0000,0000,0000,,it should inform when users are friends Dialogue: 0,0:39:38.32,0:39:41.97,Default,,0000,0000,0000,,so I'm gonna borrow these guys here Dialogue: 0,0:39:41.97,0:39:43.56,Default,,0000,0000,0000,,let's move that down Dialogue: 0,0:39:43.56,0:39:47.43,Default,,0000,0000,0000,,and what I'm gonna do is Dialogue: 0,0:39:47.43,0:39:51.05,Default,,0000,0000,0000,,you're also friend with Paul Dialogue: 0,0:39:51.05,0:39:57.61,Default,,0000,0000,0000,,and I expect it, of course Dialogue: 0,0:39:58.38,0:39:59.77,Default,,0000,0000,0000,,it should be true Dialogue: 0,0:39:59.77,0:40:05.37,Default,,0000,0000,0000,,so my Infinitest are saying that it's not true Dialogue: 0,0:40:06.39,0:40:08.33,Default,,0000,0000,0000,,now I'm gonna just implement Dialogue: 0,0:40:08.33,0:40:11.36,Default,,0000,0000,0000,,just friends dot contain Dialogue: 0,0:40:13.36,0:40:14.32,Default,,0000,0000,0000,,Paul doesn't work here Dialogue: 0,0:40:14.32,0:40:17.84,Default,,0000,0000,0000,,let's say another user Dialogue: 0,0:40:25.88,0:40:32.39,Default,,0000,0000,0000,,cool, so now I have my method in there Dialogue: 0,0:40:32.39,0:40:36.01,Default,,0000,0000,0000,,awsome so of course that is covered Dialogue: 0,0:40:36.01,0:40:38.30,Default,,0000,0000,0000,,there are ones that are not used in this one Dialogue: 0,0:40:38.30,0:40:39.78,Default,,0000,0000,0000,,that's alright Dialogue: 0,0:40:41.15,0:40:44.35,Default,,0000,0000,0000,,so this is a great point to commit Dialogue: 0,0:40:46.13,0:40:47.68,Default,,0000,0000,0000,,git status Dialogue: 0,0:40:47.68,0:40:49.33,Default,,0000,0000,0000,,git add Dialogue: 0,0:40:49.33,0:40:51.00,Default,,0000,0000,0000,,so git commit Dialogue: 0,0:40:55.17,0:41:02.88,Default,,0000,0000,0000,,is friends with method added to user Dialogue: 0,0:41:04.49,0:41:06.01,Default,,0000,0000,0000,,awesome Dialogue: 0,0:41:07.89,0:41:11.86,Default,,0000,0000,0000,,so now we can go back to our test Dialogue: 0,0:41:11.86,0:41:19.10,Default,,0000,0000,0000,,just remove all the recorded code coverage marks Dialogue: 0,0:41:20.61,0:41:24.47,Default,,0000,0000,0000,,now I have the user with the behavior that I want Dialogue: 0,0:41:24.98,0:41:26.45,Default,,0000,0000,0000,,so when we start to refactoring Dialogue: 0,0:41:26.45,0:41:28.79,Default,,0000,0000,0000,,we should try to stay in the green Dialogue: 0,0:41:28.79,0:41:30.56,Default,,0000,0000,0000,,for as long as possible Dialogue: 0,0:41:30.56,0:41:32.95,Default,,0000,0000,0000,,instead of going crazy in the refactoring Dialogue: 0,0:41:33.60,0:41:35.73,Default,,0000,0000,0000,,and say I'm gonna change everything Dialogue: 0,0:41:35.73,0:41:37.13,Default,,0000,0000,0000,,and then all the tests are broken Dialogue: 0,0:41:37.13,0:41:40.35,Default,,0000,0000,0000,,we should, every single step that we make Dialogue: 0,0:41:40.35,0:41:41.78,Default,,0000,0000,0000,,we should run our tests Dialogue: 0,0:41:41.79,0:41:44.03,Default,,0000,0000,0000,,using Infinitest, is a way works well Dialogue: 0,0:41:44.03,0:41:46.66,Default,,0000,0000,0000,,is fantastic because that Dialogue: 0,0:41:46.66,0:41:49.68,Default,,0000,0000,0000,,if you make one move save it and it runs your test Dialogue: 0,0:41:49.68,0:41:51.15,Default,,0000,0000,0000,,and then you know where you are Dialogue: 0,0:41:51.15,0:41:54.84,Default,,0000,0000,0000,,and as soon as you make one move Dialogue: 0,0:41:54.84,0:41:56.62,Default,,0000,0000,0000,,something is broken Dialogue: 0,0:41:56.62,0:42:00.22,Default,,0000,0000,0000,,so your test shows the red in there Dialogue: 0,0:42:00.22,0:42:03.78,Default,,0000,0000,0000,,you're one Ctrl+Z away to be back to green Dialogue: 0,0:42:03.78,0:42:06.12,Default,,0000,0000,0000,,you just Ctrl+Z and save it Dialogue: 0,0:42:06.12,0:42:07.31,Default,,0000,0000,0000,,you're back into green Dialogue: 0,0:42:07.31,0:42:12.24,Default,,0000,0000,0000,,so let's try to make the smallest step that we can Dialogue: 0,0:42:12.24,0:42:15.98,Default,,0000,0000,0000,,to do this refactoring and stay in the green, right? Dialogue: 0,0:42:18.76,0:42:22.14,Default,,0000,0000,0000,,so what if I say Dialogue: 0,0:42:22.14,0:42:28.77,Default,,0000,0000,0000,,what if I first of all move this boolean in here Dialogue: 0,0:42:28.77,0:42:33.92,Default,,0000,0000,0000,,because it just used inside of the if statement so I can bring Dialogue: 0,0:42:33.92,0:42:35.19,Default,,0000,0000,0000,,oh, there's another tip Dialogue: 0,0:42:35.19,0:42:36.50,Default,,0000,0000,0000,,when working with legacy code Dialogue: 0,0:42:36.50,0:42:40.32,Default,,0000,0000,0000,,normally you find variables declared all over the place Dialogue: 0,0:42:40.32,0:42:42.36,Default,,0000,0000,0000,,try to bring them together Dialogue: 0,0:42:42.36,0:42:48.22,Default,,0000,0000,0000,,try to put the blocks of code close each other Dialogue: 0,0:42:48.22,0:42:51.62,Default,,0000,0000,0000,,if the variable is not used at the top Dialogue: 0,0:42:51.62,0:42:53.04,Default,,0000,0000,0000,,it's just used at bottom Dialogue: 0,0:42:53.04,0:42:54.44,Default,,0000,0000,0000,,but it's declared at the top Dialogue: 0,0:42:54.44,0:42:55.85,Default,,0000,0000,0000,,bring that close Dialogue: 0,0:42:55.85,0:42:58.20,Default,,0000,0000,0000,,because it ??? know where the blocks are Dialogue: 0,0:42:58.20,0:43:00.85,Default,,0000,0000,0000,,and it makes you much easier to separate the code Dialogue: 0,0:43:00.85,0:43:02.89,Default,,0000,0000,0000,,so now I could say Dialogue: 0,0:43:02.89,0:43:10.14,Default,,0000,0000,0000,,is friend, I could say Dialogue: 0,0:43:10.14,0:43:16.84,Default,,0000,0000,0000,,user is friends with logged user Dialogue: 0,0:43:16.84,0:43:22.09,Default,,0000,0000,0000,,let's rename logged user to logged in user Dialogue: 0,0:43:22.09,0:43:23.94,Default,,0000,0000,0000,,so that's how I think Dialogue: 0,0:43:23.94,0:43:25.49,Default,,0000,0000,0000,,when you're dealing with legacy Dialogue: 0,0:43:25.49,0:43:28.67,Default,,0000,0000,0000,,you find names are quite weird or not quite right Dialogue: 0,0:43:28.67,0:43:29.100,Default,,0000,0000,0000,,as soon as you figured out where they are Dialogue: 0,0:43:29.100,0:43:31.70,Default,,0000,0000,0000,,just rename it quickly Dialogue: 0,0:43:31.70,0:43:33.24,Default,,0000,0000,0000,,so cool, as you can see Dialogue: 0,0:43:33.24,0:43:37.85,Default,,0000,0000,0000,,you can keep an eye on the green bar here Dialogue: 0,0:43:37.85,0:43:39.18,Default,,0000,0000,0000,,so every time that I saved it Dialogue: 0,0:43:39.18,0:43:41.22,Default,,0000,0000,0000,,it's gonna run my test Dialogue: 0,0:43:41.22,0:43:47.49,Default,,0000,0000,0000,,so now, I believe that is quite safe Dialogue: 0,0:43:47.49,0:43:49.48,Default,,0000,0000,0000,,to do this and save Dialogue: 0,0:43:49.48,0:43:52.54,Default,,0000,0000,0000,,so it ran my tests and that's green Dialogue: 0,0:43:52.54,0:43:53.67,Default,,0000,0000,0000,,so now I can delete that Dialogue: 0,0:43:54.67,0:43:57.26,Default,,0000,0000,0000,,so now that I can delete Dialogue: 0,0:43:58.34,0:44:00.46,Default,,0000,0000,0000,,I maybe able to Dialogue: 0,0:44:09.92,0:44:12.67,Default,,0000,0000,0000,,let's try to inline this Dialogue: 0,0:44:12.67,0:44:14.05,Default,,0000,0000,0000,,awesome Dialogue: 0,0:44:14.58,0:44:16.05,Default,,0000,0000,0000,,so that's cool Dialogue: 0,0:44:17.76,0:44:23.28,Default,,0000,0000,0000,,so there is a quick win as well here Dialogue: 0,0:44:23.28,0:44:25.70,Default,,0000,0000,0000,,for example, this guy here Dialogue: 0,0:44:26.39,0:44:27.72,Default,,0000,0000,0000,,it's a guard clause Dialogue: 0,0:44:27.72,0:44:30.45,Default,,0000,0000,0000,,we can transform this into guard clause Dialogue: 0,0:44:30.45,0:44:31.48,Default,,0000,0000,0000,,what is a guard clause? Dialogue: 0,0:44:31.48,0:44:33.33,Default,,0000,0000,0000,,as soon as parameter comes in Dialogue: 0,0:44:33.33,0:44:35.86,Default,,0000,0000,0000,,you invalidate parameter and throw an exception Dialogue: 0,0:44:35.86,0:44:37.43,Default,,0000,0000,0000,,that's the guard clause Dialogue: 0,0:44:37.43,0:44:39.69,Default,,0000,0000,0000,,so what we can do Dialogue: 0,0:44:40.14,0:44:44.90,Default,,0000,0000,0000,,let's transform that to guard clause Dialogue: 0,0:44:44.90,0:44:46.00,Default,,0000,0000,0000,,we can get rid of if Dialogue: 0,0:44:48.26,0:44:53.31,Default,,0000,0000,0000,,so if logged in user is null Dialogue: 0,0:44:56.29,0:44:58.16,Default,,0000,0000,0000,,then Dialogue: 0,0:45:00.34,0:45:02.56,Default,,0000,0000,0000,,let's throw an exception Dialogue: 0,0:45:03.31,0:45:06.73,Default,,0000,0000,0000,,of course that this guy need to be up Dialogue: 0,0:45:09.00,0:45:11.79,Default,,0000,0000,0000,,so as soon as I saved it Dialogue: 0,0:45:11.79,0:45:13.58,Default,,0000,0000,0000,,so I'm still in the green Dialogue: 0,0:45:14.28,0:45:19.90,Default,,0000,0000,0000,,and Eclipse kindly showing to me that this is dead code now Dialogue: 0,0:45:19.90,0:45:23.99,Default,,0000,0000,0000,,so I can delete the entire if statement Dialogue: 0,0:45:27.58,0:45:29.34,Default,,0000,0000,0000,,so if I save it Dialogue: 0,0:45:29.94,0:45:30.58,Default,,0000,0000,0000,,awesome Dialogue: 0,0:45:30.58,0:45:35.02,Default,,0000,0000,0000,,so I'm doing all these refactoring without going to the red Dialogue: 0,0:45:35.31,0:45:36.58,Default,,0000,0000,0000,,not even a single time Dialogue: 0,0:45:36.58,0:45:39.86,Default,,0000,0000,0000,,but even if I make a mistake and I go to the red Dialogue: 0,0:45:39.86,0:45:42.51,Default,,0000,0000,0000,,what normally happens in the real world Dialogue: 0,0:45:42.51,0:45:45.88,Default,,0000,0000,0000,,that's alright, I do a Ctrl+Z Dialogue: 0,0:45:45.88,0:45:47.14,Default,,0000,0000,0000,,I'm back into green Dialogue: 0,0:45:47.14,0:45:48.28,Default,,0000,0000,0000,,and I re-think what I'm doing Dialogue: 0,0:45:48.28,0:45:50.53,Default,,0000,0000,0000,,sometimes you need to go to the red Dialogue: 0,0:45:50.53,0:45:53.84,Default,,0000,0000,0000,,but I avoid it as much as I can Dialogue: 0,0:45:53.84,0:45:57.49,Default,,0000,0000,0000,,so now we have two clear blocks in here Dialogue: 0,0:45:58.93,0:46:06.30,Default,,0000,0000,0000,,the first block is about checking or validating the logged in user Dialogue: 0,0:46:06.30,0:46:13.98,Default,,0000,0000,0000,,the second block is about getting the trips from the friend Dialogue: 0,0:46:13.98,0:46:17.37,Default,,0000,0000,0000,,so we can do a few things slightly better in here Dialogue: 0,0:46:17.37,0:46:20.22,Default,,0000,0000,0000,,so for example I could say Dialogue: 0,0:46:23.23,0:46:25.92,Default,,0000,0000,0000,,getting rid of variables in legacy code Dialogue: 0,0:46:25.92,0:46:28.99,Default,,0000,0000,0000,,is another thing that you should try to do Dialogue: 0,0:46:28.99,0:46:32.18,Default,,0000,0000,0000,,because the less variables you have the easier it is Dialogue: 0,0:46:32.18,0:46:36.52,Default,,0000,0000,0000,,even if you have some redundancy in there Dialogue: 0,0:46:36.52,0:46:38.72,Default,,0000,0000,0000,,if you call method twice Dialogue: 0,0:46:38.72,0:46:41.35,Default,,0000,0000,0000,,you may sacrifice performance for a while Dialogue: 0,0:46:41.92,0:46:43.56,Default,,0000,0000,0000,,but getting rid of variable Dialogue: 0,0:46:43.56,0:46:47.10,Default,,0000,0000,0000,,cause variables are the most people ??? in long method Dialogue: 0,0:46:47.10,0:46:49.97,Default,,0000,0000,0000,,because they're set in many different places and reused Dialogue: 0,0:46:50.18,0:46:51.81,Default,,0000,0000,0000,,if you can get rid of them Dialogue: 0,0:46:51.81,0:46:55.66,Default,,0000,0000,0000,,and just invoke the same method over and over again Dialogue: 0,0:46:55.66,0:46:58.21,Default,,0000,0000,0000,,it'll be easier to read all the code Dialogue: 0,0:46:58.21,0:47:02.22,Default,,0000,0000,0000,,and then you do the optimization for ??? again, if you need to Dialogue: 0,0:47:02.22,0:47:09.58,Default,,0000,0000,0000,,so for example, what I'm trying to do here is Dialogue: 0,0:47:16.18,0:47:17.74,Default,,0000,0000,0000,,so saved it Dialogue: 0,0:47:17.74,0:47:19.36,Default,,0000,0000,0000,,I'm still in the red Dialogue: 0,0:47:19.72,0:47:25.88,Default,,0000,0000,0000,,so I believe that what I could even do is say Dialogue: 0,0:47:25.88,0:47:27.20,Default,,0000,0000,0000,,return Dialogue: 0,0:47:29.82,0:47:31.61,Default,,0000,0000,0000,,so I'm still in the green Dialogue: 0,0:47:32.60,0:47:34.68,Default,,0000,0000,0000,,so return Dialogue: 0,0:47:35.58,0:47:37.26,Default,,0000,0000,0000,,of course it don't need Dialogue: 0,0:47:37.26,0:47:40.05,Default,,0000,0000,0000,,so if I save that I'm still in the green Dialogue: 0,0:47:40.05,0:47:42.42,Default,,0000,0000,0000,,and I don't need the variable Dialogue: 0,0:47:42.42,0:47:44.07,Default,,0000,0000,0000,,don't need that Dialogue: 0,0:47:44.07,0:47:45.69,Default,,0000,0000,0000,,still in the green Dialogue: 0,0:47:45.99,0:47:49.27,Default,,0000,0000,0000,,and now that I have symmetrical Dialogue: 0,0:47:49.27,0:47:52.85,Default,,0000,0000,0000,,if I can use ternary operator Dialogue: 0,0:47:52.85,0:47:57.61,Default,,0000,0000,0000,,so I could do that for exmple Dialogue: 0,0:48:11.85,0:48:13.65,Default,,0000,0000,0000,,hopefully if I save that Dialogue: 0,0:48:13.65,0:48:14.86,Default,,0000,0000,0000,,I'm still in the green Dialogue: 0,0:48:14.86,0:48:15.85,Default,,0000,0000,0000,,awesome Dialogue: 0,0:48:15.85,0:48:17.50,Default,,0000,0000,0000,,another thing is Dialogue: 0,0:48:17.50,0:48:20.75,Default,,0000,0000,0000,,this variable here is used in two different places Dialogue: 0,0:48:20.75,0:48:22.50,Default,,0000,0000,0000,,so let's inline that Dialogue: 0,0:48:22.50,0:48:24.31,Default,,0000,0000,0000,,inline from here. yes, I can Dialogue: 0,0:48:24.31,0:48:25.53,Default,,0000,0000,0000,,it's inlined in both places Dialogue: 0,0:48:25.53,0:48:27.01,Default,,0000,0000,0000,,that's what I was talking about Dialogue: 0,0:48:27.01,0:48:28.61,Default,,0000,0000,0000,,I got rid of the variable Dialogue: 0,0:48:29.09,0:48:32.52,Default,,0000,0000,0000,,and of course I'm calling the method twice Dialogue: 0,0:48:32.52,0:48:34.89,Default,,0000,0000,0000,,but I made my code a lot simpler Dialogue: 0,0:48:34.89,0:48:36.49,Default,,0000,0000,0000,,of course if there's performance issue Dialogue: 0,0:48:36.50,0:48:39.90,Default,,0000,0000,0000,,then you extract variables again all sort of stuff Dialogue: 0,0:48:39.90,0:48:44.86,Default,,0000,0000,0000,,so that's awesome because now I'm much happier Dialogue: 0,0:48:44.94,0:48:49.04,Default,,0000,0000,0000,,and one thing that I don't even like this guy here Dialogue: 0,0:48:51.12,0:48:54.83,Default,,0000,0000,0000,,let's extract method in here, and say Dialogue: 0,0:48:54.83,0:48:58.12,Default,,0000,0000,0000,,no trips, let's make it private Dialogue: 0,0:49:01.53,0:49:03.87,Default,,0000,0000,0000,,so the cool thing about it is Dialogue: 0,0:49:05.65,0:49:07.93,Default,,0000,0000,0000,,that for example Dialogue: 0,0:49:10.15,0:49:11.77,Default,,0000,0000,0000,,if we look at the code Dialogue: 0,0:49:11.77,0:49:13.96,Default,,0000,0000,0000,,if I look at my test now Dialogue: 0,0:49:15.38,0:49:18.63,Default,,0000,0000,0000,,should throw an exception when user is not logged in Dialogue: 0,0:49:18.79,0:49:20.52,Default,,0000,0000,0000,,get logged in user Dialogue: 0,0:49:20.52,0:49:22.06,Default,,0000,0000,0000,,throw an exception Dialogue: 0,0:49:22.06,0:49:27.10,Default,,0000,0000,0000,,should not return any trips when users are not friends Dialogue: 0,0:49:27.10,0:49:29.74,Default,,0000,0000,0000,,if user is friends with logged in user Dialogue: 0,0:49:29.74,0:49:31.03,Default,,0000,0000,0000,,no trips Dialogue: 0,0:49:31.03,0:49:34.33,Default,,0000,0000,0000,,should return friend's trips when users are friends Dialogue: 0,0:49:34.33,0:49:36.32,Default,,0000,0000,0000,,so if user is friend with logged in user Dialogue: 0,0:49:36.32,0:49:37.85,Default,,0000,0000,0000,,trips by user Dialogue: 0,0:49:37.85,0:49:44.94,Default,,0000,0000,0000,,so you end up saying the same language used in the test or test names Dialogue: 0,0:49:44.94,0:49:46.23,Default,,0000,0000,0000,,being reflected in your code Dialogue: 0,0:49:46.23,0:49:47.54,Default,,0000,0000,0000,,how your code is written Dialogue: 0,0:49:47.54,0:49:49.92,Default,,0000,0000,0000,,that's one of the things that I want you to achieve Dialogue: 0,0:49:49.92,0:49:55.24,Default,,0000,0000,0000,,so that's another good place to stop and commit Dialogue: 0,0:49:55.24,0:49:56.76,Default,,0000,0000,0000,,so let's do that Dialogue: 0,0:49:56.76,0:49:59.12,Default,,0000,0000,0000,,so git status Dialogue: 0,0:49:59.42,0:50:02.16,Default,,0000,0000,0000,,git commit Dialogue: 0,0:50:03.36,0:50:07.54,Default,,0000,0000,0000,,trip service refactored Dialogue: 0,0:50:09.19,0:50:09.90,Default,,0000,0000,0000,,cool Dialogue: 0,0:50:12.34,0:50:13.74,Default,,0000,0000,0000,,so that's awesome Dialogue: 0,0:50:15.38,0:50:19.79,Default,,0000,0000,0000,,so we may think that this is good, right? Dialogue: 0,0:50:20.30,0:50:21.52,Default,,0000,0000,0000,,we are done Dialogue: 0,0:50:22.36,0:50:23.28,Default,,0000,0000,0000,,but NO. Dialogue: 0,0:50:23.28,0:50:26.26,Default,,0000,0000,0000,,we are far from being done Dialogue: 0,0:50:27.84,0:50:30.30,Default,,0000,0000,0000,,see, there's tiny piece of code Dialogue: 0,0:50:30.72,0:50:35.41,Default,,0000,0000,0000,,but for example, we have enormous problems Dialogue: 0,0:50:36.27,0:50:39.07,Default,,0000,0000,0000,,one of the problem is Dialogue: 0,0:50:39.07,0:50:40.61,Default,,0000,0000,0000,,what we've done here is Dialogue: 0,0:50:40.61,0:50:45.54,Default,,0000,0000,0000,,we took a piece of untested legacy code Dialogue: 0,0:50:45.90,0:50:48.44,Default,,0000,0000,0000,,and then we wrote test straight Dialogue: 0,0:50:48.44,0:50:50.11,Default,,0000,0000,0000,,and when we do that Dialogue: 0,0:50:50.11,0:50:52.27,Default,,0000,0000,0000,,that's great, that's awesome Dialogue: 0,0:50:52.27,0:50:55.85,Default,,0000,0000,0000,,cause then we feel confident that we can change it Dialogue: 0,0:50:55.85,0:50:59.07,Default,,0000,0000,0000,,(???) Dialogue: 0,0:50:59.07,0:51:02.05,Default,,0000,0000,0000,,but the drawback is that Dialogue: 0,0:51:02.05,0:51:04.36,Default,,0000,0000,0000,,what if the design is wrong? Dialogue: 0,0:51:05.94,0:51:07.73,Default,,0000,0000,0000,,cause if the design is wrong Dialogue: 0,0:51:08.48,0:51:10.10,Default,,0000,0000,0000,,what we're doing when we write test Dialogue: 0,0:51:10.10,0:51:12.52,Default,,0000,0000,0000,,we're perpetuating that design Dialogue: 0,0:51:13.06,0:51:14.69,Default,,0000,0000,0000,,so we need to be very careful Dialogue: 0,0:51:14.69,0:51:18.94,Default,,0000,0000,0000,,because if we're not very inclined to change the design Dialogue: 0,0:51:18.94,0:51:22.33,Default,,0000,0000,0000,,and now we have a battery of test covering that stuff Dialogue: 0,0:51:22.33,0:51:24.00,Default,,0000,0000,0000,,we're far less inclined now(???) Dialogue: 0,0:51:24.00,0:51:25.45,Default,,0000,0000,0000,,because as soon as we start to change design Dialogue: 0,0:51:25.45,0:51:26.92,Default,,0000,0000,0000,,you'll break all those tests Dialogue: 0,0:51:26.92,0:51:28.57,Default,,0000,0000,0000,,so you need to be careful with that Dialogue: 0,0:51:28.57,0:51:32.11,Default,,0000,0000,0000,,and why the design here is wrong? Dialogue: 0,0:51:32.50,0:51:35.05,Default,,0000,0000,0000,,well, by the name Dialogue: 0,0:51:35.78,0:51:41.25,Default,,0000,0000,0000,,I assume the trip service is a server side class Dialogue: 0,0:51:41.25,0:51:42.73,Default,,0000,0000,0000,,belongs to the Model Dialogue: 0,0:51:44.02,0:51:51.18,Default,,0000,0000,0000,,but then it has a dependency on the user session, right? Dialogue: 0,0:51:51.18,0:51:57.02,Default,,0000,0000,0000,,so your Model shouldn't know anything about the web framework Dialogue: 0,0:51:57.02,0:52:01.13,Default,,0000,0000,0000,,shouldn't know anything about http session or anything like that Dialogue: 0,0:52:01.69,0:52:05.01,Default,,0000,0000,0000,,so, that's the problem with the design that this class has Dialogue: 0,0:52:05.01,0:52:09.59,Default,,0000,0000,0000,,so we need to solve that Dialogue: 0,0:52:10.02,0:52:11.82,Default,,0000,0000,0000,,one way to solve that is Dialogue: 0,0:52:11.82,0:52:17.19,Default,,0000,0000,0000,,we should pass the logged in user as parameter to this method Dialogue: 0,0:52:17.19,0:52:23.50,Default,,0000,0000,0000,,so now I'm gonna make sort of dangerous refactoring Dialogue: 0,0:52:23.50,0:52:26.18,Default,,0000,0000,0000,,that it will be ok for this exercise Dialogue: 0,0:52:26.18,0:52:28.54,Default,,0000,0000,0000,,but if you do that in a normal production environment Dialogue: 0,0:52:28.54,0:52:29.66,Default,,0000,0000,0000,,you need to be very careful Dialogue: 0,0:52:29.66,0:52:31.32,Default,,0000,0000,0000,,so I want to pass Dialogue: 0,0:52:31.32,0:52:32.100,Default,,0000,0000,0000,,I'll try to do, as always Dialogue: 0,0:52:32.100,0:52:35.20,Default,,0000,0000,0000,,baby steps, bit by bit Dialogue: 0,0:52:35.20,0:52:40.28,Default,,0000,0000,0000,,so for example I want to pass the logged in user as parameter Dialogue: 0,0:52:40.28,0:52:42.90,Default,,0000,0000,0000,,so what I can do is Dialogue: 0,0:52:42.90,0:52:46.28,Default,,0000,0000,0000,,I go to refactor Dialogue: 0,0:52:46.28,0:52:48.23,Default,,0000,0000,0000,,change method signature Dialogue: 0,0:52:48.23,0:52:50.89,Default,,0000,0000,0000,,and I'm gonna add a new parameter Dialogue: 0,0:52:51.11,0:52:52.99,Default,,0000,0000,0000,,I'm gonna call user Dialogue: 0,0:52:55.36,0:52:59.25,Default,,0000,0000,0000,,logged in user, right? Dialogue: 0,0:52:59.25,0:53:00.91,Default,,0000,0000,0000,,and the default is null Dialogue: 0,0:53:01.50,0:53:04.34,Default,,0000,0000,0000,,so that's cool Dialogue: 0,0:53:04.40,0:53:07.70,Default,,0000,0000,0000,,because eclipse does great job in refactoring Dialogue: 0,0:53:07.70,0:53:09.61,Default,,0000,0000,0000,,IntelliJ does same Dialogue: 0,0:53:09.61,0:53:12.63,Default,,0000,0000,0000,,so this guy was passed in as parameter Dialogue: 0,0:53:12.63,0:53:14.53,Default,,0000,0000,0000,,it's not used anywhere else Dialogue: 0,0:53:14.53,0:53:17.58,Default,,0000,0000,0000,,but it changed in my test Dialogue: 0,0:53:17.58,0:53:22.74,Default,,0000,0000,0000,,it changed the method signature to pass null, everywhere, right? Dialogue: 0,0:53:23.22,0:53:25.57,Default,,0000,0000,0000,,so that's cool, that's great Dialogue: 0,0:53:25.57,0:53:28.63,Default,,0000,0000,0000,,the only problem is, for example Dialogue: 0,0:53:28.63,0:53:31.51,Default,,0000,0000,0000,,this method here being a production method Dialogue: 0,0:53:31.51,0:53:33.52,Default,,0000,0000,0000,,it's probably used Dialogue: 0,0:53:33.52,0:53:37.26,Default,,0000,0000,0000,,or it's probably invoked by other classes Dialogue: 0,0:53:37.26,0:53:44.54,Default,,0000,0000,0000,,and now all the other places where this method here is invoked Dialogue: 0,0:53:44.54,0:53:47.36,Default,,0000,0000,0000,,the production code is passing null as well Dialogue: 0,0:53:47.36,0:53:49.69,Default,,0000,0000,0000,,so you need to go back there and fix that Dialogue: 0,0:53:49.69,0:53:51.90,Default,,0000,0000,0000,,so you just need to bear that in mind Dialogue: 0,0:53:52.86,0:53:56.20,Default,,0000,0000,0000,,but for the sake of this exercise Dialogue: 0,0:53:58.50,0:53:59.78,Default,,0000,0000,0000,,so what we want to do Dialogue: 0,0:53:59.78,0:54:00.82,Default,,0000,0000,0000,,we want to do fix our test Dialogue: 0,0:54:00.82,0:54:03.64,Default,,0000,0000,0000,,cause we don't want this nulls hanging in around Dialogue: 0,0:54:03.64,0:54:05.13,Default,,0000,0000,0000,,and this is the logged user Dialogue: 0,0:54:05.13,0:54:07.72,Default,,0000,0000,0000,,so I'm gonna pass here, a guest Dialogue: 0,0:54:07.72,0:54:09.76,Default,,0000,0000,0000,,because that's what I would pass Dialogue: 0,0:54:11.75,0:54:15.23,Default,,0000,0000,0000,,so as always I'm looking at my Infinitest Dialogue: 0,0:54:15.23,0:54:22.11,Default,,0000,0000,0000,,so here I'm gonna pass my logged in user Dialogue: 0,0:54:22.11,0:54:24.43,Default,,0000,0000,0000,,here I'm gonna pass Dialogue: 0,0:54:26.62,0:54:30.34,Default,,0000,0000,0000,,yeah, I'm gonna pass my logged in user here Dialogue: 0,0:54:36.23,0:54:37.50,Default,,0000,0000,0000,,so that's cool Dialogue: 0,0:54:37.50,0:54:39.40,Default,,0000,0000,0000,,just to make sure that everything is ok Dialogue: 0,0:54:39.40,0:54:40.72,Default,,0000,0000,0000,,so cool Dialogue: 0,0:54:41.79,0:54:45.38,Default,,0000,0000,0000,,now I want to start using this parameter Dialogue: 0,0:54:46.71,0:54:48.29,Default,,0000,0000,0000,,so what I'll do Dialogue: 0,0:54:49.11,0:54:53.52,Default,,0000,0000,0000,,I'll just use the parameter Dialogue: 0,0:54:53.52,0:54:59.11,Default,,0000,0000,0000,,I'm just gonna rename that to this Dialogue: 0,0:54:59.11,0:55:04.05,Default,,0000,0000,0000,,rename that to this Dialogue: 0,0:55:04.05,0:55:06.68,Default,,0000,0000,0000,,so this is the parameter now Dialogue: 0,0:55:06.68,0:55:08.57,Default,,0000,0000,0000,,so if i save it Dialogue: 0,0:55:11.29,0:55:14.09,Default,,0000,0000,0000,,and so all my tests are green Dialogue: 0,0:55:14.09,0:55:16.35,Default,,0000,0000,0000,,so that means that this guy Dialogue: 0,0:55:16.35,0:55:18.58,Default,,0000,0000,0000,,transform that in private Dialogue: 0,0:55:18.58,0:55:22.05,Default,,0000,0000,0000,,so eclipse say that it's not been used Dialogue: 0,0:55:22.05,0:55:25.29,Default,,0000,0000,0000,,so I can delete safely Dialogue: 0,0:55:26.34,0:55:29.61,Default,,0000,0000,0000,,and of course, as soon as I delete my test Dialogue: 0,0:55:29.61,0:55:32.30,Default,,0000,0000,0000,,I just need to delete this guy Dialogue: 0,0:55:32.30,0:55:35.73,Default,,0000,0000,0000,,and everything is back to green Dialogue: 0,0:55:35.73,0:55:37.24,Default,,0000,0000,0000,,so now I'm using the parameter Dialogue: 0,0:55:37.24,0:55:40.05,Default,,0000,0000,0000,,I made my refactoring Dialogue: 0,0:55:40.93,0:55:43.15,Default,,0000,0000,0000,,(???) thing that I can do is Dialogue: 0,0:55:43.15,0:55:45.60,Default,,0000,0000,0000,,this logged in user Dialogue: 0,0:55:45.95,0:55:48.53,Default,,0000,0000,0000,,I probably don't need that anymore Dialogue: 0,0:55:48.53,0:55:54.68,Default,,0000,0000,0000,,so if I replace this one by these guys here Dialogue: 0,0:55:55.60,0:55:58.93,Default,,0000,0000,0000,,and I put this guy here Dialogue: 0,0:56:02.06,0:56:05.91,Default,,0000,0000,0000,,so one way to know if Dialogue: 0,0:56:05.91,0:56:10.25,Default,,0000,0000,0000,,so now for example, eclipse is saying that this variable is not being used Dialogue: 0,0:56:10.25,0:56:14.30,Default,,0000,0000,0000,,so now I can delete that Dialogue: 0,0:56:14.30,0:56:16.93,Default,,0000,0000,0000,,and delete that Dialogue: 0,0:56:16.93,0:56:19.14,Default,,0000,0000,0000,,delete that Dialogue: 0,0:56:19.14,0:56:22.95,Default,,0000,0000,0000,,and everything is green Dialogue: 0,0:56:22.95,0:56:26.40,Default,,0000,0000,0000,,so this is a perfect place to commit again Dialogue: 0,0:56:26.40,0:56:29.17,Default,,0000,0000,0000,,oh, by the way, there is a warning here Dialogue: 0,0:56:29.17,0:56:32.75,Default,,0000,0000,0000,,so should always get rid of the unused import Dialogue: 0,0:56:32.75,0:56:35.14,Default,,0000,0000,0000,,because rubbish thing around (???) Dialogue: 0,0:56:35.14,0:56:37.13,Default,,0000,0000,0000,,so craftsman ship is important Dialogue: 0,0:56:37.13,0:56:38.84,Default,,0000,0000,0000,,keep it clean Dialogue: 0,0:56:39.83,0:56:42.41,Default,,0000,0000,0000,,so cool, that's a great place to stop Dialogue: 0,0:56:42.41,0:56:44.40,Default,,0000,0000,0000,,so let's say Dialogue: 0,0:56:45.17,0:56:47.03,Default,,0000,0000,0000,,git commit Dialogue: 0,0:56:50.33,0:57:00.54,Default,,0000,0000,0000,,logged in user passed into trip service Dialogue: 0,0:57:01.73,0:57:03.62,Default,,0000,0000,0000,,cool, awesome Dialogue: 0,0:57:06.47,0:57:08.88,Default,,0000,0000,0000,,so maybe now we're done Dialogue: 0,0:57:10.57,0:57:12.100,Default,,0000,0000,0000,,sort of, sort of Dialogue: 0,0:57:12.100,0:57:17.13,Default,,0000,0000,0000,,I still don't like this thing in here Dialogue: 0,0:57:17.90,0:57:19.32,Default,,0000,0000,0000,,this trip dao thing Dialogue: 0,0:57:19.32,0:57:21.26,Default,,0000,0000,0000,,I don't like the statical Dialogue: 0,0:57:21.26,0:57:25.34,Default,,0000,0000,0000,,this statical makes me do this thing that Dialogue: 0,0:57:25.34,0:57:30.17,Default,,0000,0000,0000,,as I said this is sort of intermediately step Dialogue: 0,0:57:30.18,0:57:33.86,Default,,0000,0000,0000,,ideally I would inject trip dao in there Dialogue: 0,0:57:34.10,0:57:36.25,Default,,0000,0000,0000,,using an instance method Dialogue: 0,0:57:36.35,0:57:38.95,Default,,0000,0000,0000,,but because it's static method, I can't do much Dialogue: 0,0:57:38.95,0:57:41.40,Default,,0000,0000,0000,,I can't really inject that, right? Dialogue: 0,0:57:41.40,0:57:42.72,Default,,0000,0000,0000,,cause this is always Dialogue: 0,0:57:42.72,0:57:46.33,Default,,0000,0000,0000,,you mean normally inject an instance not class Dialogue: 0,0:57:46.33,0:57:48.19,Default,,0000,0000,0000,,so it doesn't work Dialogue: 0,0:57:48.19,0:57:50.80,Default,,0000,0000,0000,,so I want to go further Dialogue: 0,0:57:50.80,0:57:52.61,Default,,0000,0000,0000,,I want go get rid of this Dialogue: 0,0:57:52.61,0:57:56.26,Default,,0000,0000,0000,,I want to have a instance method in my trip dao Dialogue: 0,0:57:56.26,0:57:57.69,Default,,0000,0000,0000,,so let's open my trip dao Dialogue: 0,0:57:57.69,0:57:59.09,Default,,0000,0000,0000,,let's see what it does Dialogue: 0,0:57:59.09,0:58:00.42,Default,,0000,0000,0000,,so of course that in this case Dialogue: 0,0:58:00.42,0:58:02.49,Default,,0000,0000,0000,,it is just like a toy example Dialogue: 0,0:58:02.49,0:58:04.65,Default,,0000,0000,0000,,so you just throw an exception Dialogue: 0,0:58:06.11,0:58:10.39,Default,,0000,0000,0000,,as I said before in a normal circumstance Dialogue: 0,0:58:10.39,0:58:11.89,Default,,0000,0000,0000,,this would go to database Dialogue: 0,0:58:11.89,0:58:12.96,Default,,0000,0000,0000,,or to distributed cache Dialogue: 0,0:58:12.96,0:58:18.24,Default,,0000,0000,0000,,or whatever persistence mechanism you have Dialogue: 0,0:58:19.15,0:58:21.29,Default,,0000,0000,0000,,so what I want to do Dialogue: 0,0:58:22.01,0:58:28.97,Default,,0000,0000,0000,,I want to create an instance method for that Dialogue: 0,0:58:30.39,0:58:35.45,Default,,0000,0000,0000,,so I'm gonna write a test for it Dialogue: 0,0:58:37.56,0:58:39.05,Default,,0000,0000,0000,,let's say Dialogue: 0,0:58:42.94,0:58:45.72,Default,,0000,0000,0000,,trip dao test Dialogue: 0,0:58:47.33,0:58:49.16,Default,,0000,0000,0000,,let's put into test Dialogue: 0,0:58:51.65,0:58:53.73,Default,,0000,0000,0000,,so this is an interesting one Dialogue: 0,0:58:55.57,0:58:56.98,Default,,0000,0000,0000,,it's an interesting trick Dialogue: 0,0:58:58.13,0:59:03.33,Default,,0000,0000,0000,,so I want an instance method Dialogue: 0,0:59:03.33,0:59:08.53,Default,,0000,0000,0000,,that does everything that the static method does Dialogue: 0,0:59:11.53,0:59:13.29,Default,,0000,0000,0000,,same behavior, just Dialogue: 0,0:59:15.66,0:59:18.44,Default,,0000,0000,0000,,you could say, well, just remove static method Dialogue: 0,0:59:18.44,0:59:22.55,Default,,0000,0000,0000,,just remove the static keyword from there Dialogue: 0,0:59:22.55,0:59:23.90,Default,,0000,0000,0000,,yes, I could Dialogue: 0,0:59:23.90,0:59:24.96,Default,,0000,0000,0000,,but if I do that Dialogue: 0,0:59:24.96,0:59:27.57,Default,,0000,0000,0000,,I'll need to fix my entire code base Dialogue: 0,0:59:27.57,0:59:31.95,Default,,0000,0000,0000,,because, let's assume that there are many classes in my application Dialogue: 0,0:59:32.33,0:59:35.28,Default,,0000,0000,0000,,that are using this static method Dialogue: 0,0:59:35.28,0:59:37.96,Default,,0000,0000,0000,,as soon as I transform this one into instance Dialogue: 0,0:59:37.96,0:59:39.73,Default,,0000,0000,0000,,I'll break entire code base Dialogue: 0,0:59:39.73,0:59:42.52,Default,,0000,0000,0000,,and that'll be much bigger refactoring to do Dialogue: 0,0:59:42.52,0:59:45.50,Default,,0000,0000,0000,,and we want to do everything in small steps Dialogue: 0,0:59:46.07,0:59:48.29,Default,,0000,0000,0000,,so what I'll do Dialogue: 0,0:59:49.17,0:59:51.20,Default,,0000,0000,0000,,I create a test, let's say Dialogue: 0,0:59:51.20,0:59:53.13,Default,,0000,0000,0000,,I'll just mimic this behavior Dialogue: 0,0:59:53.13,0:59:54.93,Default,,0000,0000,0000,,so don't take this test too seriously Dialogue: 0,0:59:54.93,0:59:57.43,Default,,0000,0000,0000,,just get the idea of what I'm doing Dialogue: 0,0:59:57.43,1:00:00.78,Default,,0000,0000,0000,,but I'll just represent what this method currently does Dialogue: 0,1:00:00.78,1:00:19.86,Default,,0000,0000,0000,,so should throw exception when retrieving user trips Dialogue: 0,1:00:21.30,1:00:25.90,Default,,0000,0000,0000,,so I want this to throw an exception Dialogue: 0,1:00:27.90,1:00:29.80,Default,,0000,0000,0000,,as I said Dialogue: 0,1:00:29.80,1:00:33.70,Default,,0000,0000,0000,,ideally this would go to the database or something Dialogue: 0,1:00:33.73,1:00:35.91,Default,,0000,0000,0000,,I'm just preserving the same behavior Dialogue: 0,1:00:35.91,1:00:40.41,Default,,0000,0000,0000,,so dependent class call during unit test blah blah Dialogue: 0,1:00:40.41,1:00:41.87,Default,,0000,0000,0000,,so that's the exception thrown Dialogue: 0,1:00:41.87,1:00:44.68,Default,,0000,0000,0000,,but I want an instance method Dialogue: 0,1:00:44.68,1:00:47.84,Default,,0000,0000,0000,,so just invoking the method should be enough Dialogue: 0,1:00:47.84,1:00:49.23,Default,,0000,0000,0000,,so what I can do Dialogue: 0,1:00:49.23,1:00:51.71,Default,,0000,0000,0000,,new trip dao Dialogue: 0,1:00:54.72,1:01:06.02,Default,,0000,0000,0000,,let's call it trips by user Dialogue: 0,1:01:09.73,1:01:13.18,Default,,0000,0000,0000,,so I want an instance method Dialogue: 0,1:01:14.84,1:01:16.13,Default,,0000,0000,0000,,that throws an exception Dialogue: 0,1:01:16.13,1:01:18.28,Default,,0000,0000,0000,,so I'm gonna create this method Dialogue: 0,1:01:18.77,1:01:26.24,Default,,0000,0000,0000,,I'm gonna make it return the same thing as the other one Dialogue: 0,1:01:32.74,1:01:34.97,Default,,0000,0000,0000,,so my test is failing, of course Dialogue: 0,1:01:34.97,1:01:37.14,Default,,0000,0000,0000,,so now what I want this to do Dialogue: 0,1:01:37.14,1:01:39.52,Default,,0000,0000,0000,,it should behave exactly like this static method Dialogue: 0,1:01:39.52,1:01:43.10,Default,,0000,0000,0000,,so what I do is trip dao dot Dialogue: 0,1:01:45.04,1:01:51.63,Default,,0000,0000,0000,,I just invoke from the instance method Dialogue: 0,1:01:51.63,1:01:53.09,Default,,0000,0000,0000,,invoke the static one Dialogue: 0,1:01:54.00,1:01:55.55,Default,,0000,0000,0000,,why do I do that? Dialogue: 0,1:01:55.55,1:01:56.81,Default,,0000,0000,0000,,the cool thing is that Dialogue: 0,1:01:57.07,1:02:02.57,Default,,0000,0000,0000,,as I start moving my code to use this one Dialogue: 0,1:02:04.79,1:02:06.33,Default,,0000,0000,0000,,so now what I'm gonna do Dialogue: 0,1:02:06.33,1:02:09.36,Default,,0000,0000,0000,,I'm gonna replace the trip service used the instance method Dialogue: 0,1:02:09.40,1:02:11.23,Default,,0000,0000,0000,,and imagine that I start doing that Dialogue: 0,1:02:11.23,1:02:13.16,Default,,0000,0000,0000,,for all the other class that used static Dialogue: 0,1:02:13.16,1:02:19.12,Default,,0000,0000,0000,,until there's no class referencing the static method anymore Dialogue: 0,1:02:19.12,1:02:20.04,Default,,0000,0000,0000,,and what I can do Dialogue: 0,1:02:20.04,1:02:21.63,Default,,0000,0000,0000,,I just can copy this behavior Dialogue: 0,1:02:21.63,1:02:24.32,Default,,0000,0000,0000,,paste it into here and delete the static method Dialogue: 0,1:02:24.32,1:02:25.57,Default,,0000,0000,0000,,and then I'm done Dialogue: 0,1:02:25.57,1:02:27.21,Default,,0000,0000,0000,,so that's the trick Dialogue: 0,1:02:27.21,1:02:28.86,Default,,0000,0000,0000,,so going back to Dialogue: 0,1:02:28.86,1:02:35.02,Default,,0000,0000,0000,,so now my trip dao has the instance method Dialogue: 0,1:02:35.02,1:02:38.48,Default,,0000,0000,0000,,so what I need to do now Dialogue: 0,1:02:38.48,1:02:43.62,Default,,0000,0000,0000,,is to have a reason to inject this trip dao in there Dialogue: 0,1:02:44.08,1:02:46.02,Default,,0000,0000,0000,,so now I'm gonna Dialogue: 0,1:02:46.02,1:02:48.76,Default,,0000,0000,0000,,there are quite of few ways of doing that like for example Dialogue: 0,1:02:48.76,1:02:51.22,Default,,0000,0000,0000,,I could use normal dependency injection with no framework Dialogue: 0,1:02:51.22,1:02:55.12,Default,,0000,0000,0000,,just pass the trip dao into the constructor of the trip service Dialogue: 0,1:02:55.12,1:02:57.20,Default,,0000,0000,0000,,for example, that's one way of doing it Dialogue: 0,1:02:57.20,1:02:59.49,Default,,0000,0000,0000,,and that's the simplest way Dialogue: 0,1:02:59.49,1:03:02.78,Default,,0000,0000,0000,,as I know that majority of people that use java Dialogue: 0,1:03:02.78,1:03:05.84,Default,,0000,0000,0000,,they use spring and they use mockito and stuff like that Dialogue: 0,1:03:05.90,1:03:08.34,Default,,0000,0000,0000,,I'll show you how it would work in mockito Dialogue: 0,1:03:08.34,1:03:10.70,Default,,0000,0000,0000,,but for now, if you don't use mockito Dialogue: 0,1:03:10.70,1:03:11.66,Default,,0000,0000,0000,,then that's it Dialogue: 0,1:03:11.72,1:03:16.51,Default,,0000,0000,0000,,create a constructor pass the trip dao to the constructor Dialogue: 0,1:03:16.84,1:03:19.25,Default,,0000,0000,0000,,I'm just gonna do with mockito and spring Dialogue: 0,1:03:19.25,1:03:21.76,Default,,0000,0000,0000,,just to show what you can do basically Dialogue: 0,1:03:21.83,1:03:26.68,Default,,0000,0000,0000,,so I want now to have a broken test Dialogue: 0,1:03:26.68,1:03:30.61,Default,,0000,0000,0000,,that justifies me to inject a trip dao in there Dialogue: 0,1:03:30.61,1:03:33.27,Default,,0000,0000,0000,,so, I'm gonna say run with Dialogue: 0,1:03:33.32,1:03:35.94,Default,,0000,0000,0000,,I'm gonna use JUnit with mockito Dialogue: 0,1:03:36.03,1:03:37.27,Default,,0000,0000,0000,,mockito runner Dialogue: 0,1:03:37.34,1:03:39.09,Default,,0000,0000,0000,,junit runner Dialogue: 0,1:03:42.06,1:03:46.70,Default,,0000,0000,0000,,so if you don't use mockito and the junit in spring (???) Dialogue: 0,1:03:46.70,1:03:48.41,Default,,0000,0000,0000,,maybe a bit complicated Dialogue: 0,1:03:48.41,1:03:52.30,Default,,0000,0000,0000,,so I recommend that you read the documentation of all these frameworks Dialogue: 0,1:03:54.54,1:04:00.89,Default,,0000,0000,0000,,so far, I've been using the testable trip service Dialogue: 0,1:04:00.89,1:04:03.11,Default,,0000,0000,0000,,that class we created before Dialogue: 0,1:04:03.86,1:04:06.76,Default,,0000,0000,0000,,now I want to start using the real one Dialogue: 0,1:04:06.76,1:04:09.05,Default,,0000,0000,0000,,the real one and injecting Dialogue: 0,1:04:09.05,1:04:12.57,Default,,0000,0000,0000,,cause I don't want these thing here anymore Dialogue: 0,1:04:12.57,1:04:15.09,Default,,0000,0000,0000,,I don't want this madness here anymore Dialogue: 0,1:04:15.62,1:04:18.62,Default,,0000,0000,0000,,I want to just to be able mock to my dependency Dialogue: 0,1:04:18.62,1:04:21.30,Default,,0000,0000,0000,,so I'll create another Dialogue: 0,1:04:21.30,1:04:23.77,Default,,0000,0000,0000,,do that in very small steps Dialogue: 0,1:04:24.22,1:04:25.54,Default,,0000,0000,0000,,trip service Dialogue: 0,1:04:27.48,1:04:36.76,Default,,0000,0000,0000,,I'll call for now real trip service new trip service Dialogue: 0,1:04:36.76,1:04:38.41,Default,,0000,0000,0000,,that's the real one Dialogue: 0,1:04:38.41,1:04:41.14,Default,,0000,0000,0000,,I'm gonna create a mock Dialogue: 0,1:04:52.35,1:04:54.69,Default,,0000,0000,0000,,I'm gonna create a mock to my dao Dialogue: 0,1:05:00.49,1:05:02.74,Default,,0000,0000,0000,,I'm gonna use mockito, to say Dialogue: 0,1:05:04.36,1:05:06.03,Default,,0000,0000,0000,,inject mocks Dialogue: 0,1:05:06.03,1:05:09.85,Default,,0000,0000,0000,,and I'm gonna spy on it Dialogue: 0,1:05:11.25,1:05:20.64,Default,,0000,0000,0000,,so basically it's out of scope for me to explain how mockito works Dialogue: 0,1:05:20.64,1:05:25.92,Default,,0000,0000,0000,,but basically in very short explanation Dialogue: 0,1:05:25.92,1:05:27.64,Default,,0000,0000,0000,,I'm creating the real class Dialogue: 0,1:05:27.64,1:05:30.40,Default,,0000,0000,0000,,I'm asking mockito to spy on the real class Dialogue: 0,1:05:31.00,1:05:35.16,Default,,0000,0000,0000,,and to inject all the mocks that this class may have Dialogue: 0,1:05:35.16,1:05:36.97,Default,,0000,0000,0000,,I create the mock in here Dialogue: 0,1:05:36.97,1:05:40.76,Default,,0000,0000,0000,,I just need to inform that this class is expecting this mock Dialogue: 0,1:05:41.79,1:05:43.75,Default,,0000,0000,0000,,so but before I go there Dialogue: 0,1:05:43.75,1:05:46.92,Default,,0000,0000,0000,,I'm gonna, now I'm using the real trip service in here Dialogue: 0,1:05:46.92,1:05:48.61,Default,,0000,0000,0000,,I'm gonna where it breaks Dialogue: 0,1:05:48.61,1:05:49.41,Default,,0000,0000,0000,,so for example Dialogue: 0,1:05:49.41,1:05:51.11,Default,,0000,0000,0000,,I can go bit by bit, I can say Dialogue: 0,1:05:51.11,1:05:55.04,Default,,0000,0000,0000,,real trip service and save Dialogue: 0,1:05:56.35,1:05:59.96,Default,,0000,0000,0000,,so my test still green Dialogue: 0,1:06:00.68,1:06:02.95,Default,,0000,0000,0000,,so because what I'm trying to do Dialogue: 0,1:06:02.95,1:06:05.56,Default,,0000,0000,0000,,I'm trying to get rid of this guy now Dialogue: 0,1:06:05.92,1:06:06.98,Default,,0000,0000,0000,,bit by bit Dialogue: 0,1:06:07.58,1:06:08.99,Default,,0000,0000,0000,,to replace with a real one Dialogue: 0,1:06:09.57,1:06:11.08,Default,,0000,0000,0000,,so real trip service Dialogue: 0,1:06:11.35,1:06:13.38,Default,,0000,0000,0000,,so if I do that Dialogue: 0,1:06:13.92,1:06:16.27,Default,,0000,0000,0000,,it works, cool Dialogue: 0,1:06:16.28,1:06:17.41,Default,,0000,0000,0000,,the reason it works Dialogue: 0,1:06:17.41,1:06:20.46,Default,,0000,0000,0000,,because none of those test that use, they go the dao Dialogue: 0,1:06:20.46,1:06:22.37,Default,,0000,0000,0000,,none of them get to this line Dialogue: 0,1:06:23.69,1:06:30.83,Default,,0000,0000,0000,,so this one, real trip service Dialogue: 0,1:06:31.79,1:06:34.69,Default,,0000,0000,0000,,so now it breaks, right? Dialogue: 0,1:06:34.69,1:06:36.61,Default,,0000,0000,0000,,that's what I was looking for Dialogue: 0,1:06:36.61,1:06:38.55,Default,,0000,0000,0000,,now it breaks because Dialogue: 0,1:06:38.55,1:06:44.20,Default,,0000,0000,0000,,I'm using in the test the real trip service Dialogue: 0,1:06:44.20,1:06:47.67,Default,,0000,0000,0000,,and that calls the static method in the trip dao Dialogue: 0,1:06:47.67,1:06:49.10,Default,,0000,0000,0000,,and that throws an exception Dialogue: 0,1:06:49.10,1:06:51.09,Default,,0000,0000,0000,,so cool, now I have a broken test Dialogue: 0,1:06:51.09,1:06:54.25,Default,,0000,0000,0000,,so I have a reason to change my production code Dialogue: 0,1:06:56.63,1:06:59.48,Default,,0000,0000,0000,,so what I'll do Dialogue: 0,1:06:59.51,1:07:02.19,Default,,0000,0000,0000,,I'll go to my production code and say Dialogue: 0,1:07:02.19,1:07:03.90,Default,,0000,0000,0000,,if I'm using spring Dialogue: 0,1:07:04.27,1:07:05.72,Default,,0000,0000,0000,,auto wired Dialogue: 0,1:07:17.86,1:07:21.98,Default,,0000,0000,0000,,so just import the auto wired Dialogue: 0,1:07:21.98,1:07:25.45,Default,,0000,0000,0000,,so imagine that if you gonna define the trip dao in a spring bean Dialogue: 0,1:07:25.45,1:07:26.53,Default,,0000,0000,0000,,in a xml Dialogue: 0,1:07:26.53,1:07:31.57,Default,,0000,0000,0000,,so private trip dao trip dao Dialogue: 0,1:07:31.57,1:07:32.70,Default,,0000,0000,0000,,awesome Dialogue: 0,1:07:35.16,1:07:36.83,Default,,0000,0000,0000,,maximize that Dialogue: 0,1:07:38.19,1:07:40.19,Default,,0000,0000,0000,,so cool Dialogue: 0,1:07:40.22,1:07:41.82,Default,,0000,0000,0000,,so what mockito will do Dialogue: 0,1:07:41.82,1:07:43.84,Default,,0000,0000,0000,,mockito will take this guy here Dialogue: 0,1:07:43.85,1:07:46.60,Default,,0000,0000,0000,,mymock and inject into this guy here Dialogue: 0,1:07:49.43,1:07:52.01,Default,,0000,0000,0000,,so now I need to start using that Dialogue: 0,1:07:52.40,1:07:54.74,Default,,0000,0000,0000,,so my test is broken Dialogue: 0,1:07:54.98,1:07:56.95,Default,,0000,0000,0000,,and I need to start using that Dialogue: 0,1:07:56.95,1:08:02.40,Default,,0000,0000,0000,,so in here, instead of using the Dialogue: 0,1:08:04.89,1:08:07.21,Default,,0000,0000,0000,,so if I run, I just run a test Dialogue: 0,1:08:07.21,1:08:09.92,Default,,0000,0000,0000,,just to show you the difference Dialogue: 0,1:08:29.43,1:08:30.89,Default,,0000,0000,0000,,run as Dialogue: 0,1:08:32.75,1:08:35.01,Default,,0000,0000,0000,,I keep pressing wrong button Dialogue: 0,1:08:35.08,1:08:39.91,Default,,0000,0000,0000,,so it's due to using the real dao, right? Dialogue: 0,1:08:39.91,1:08:45.32,Default,,0000,0000,0000,,so what we're gonna do is replace with the instance Dialogue: 0,1:08:45.32,1:08:49.47,Default,,0000,0000,0000,,and say use the instance method Dialogue: 0,1:08:49.47,1:08:51.46,Default,,0000,0000,0000,,instead of this classic one Dialogue: 0,1:08:52.36,1:08:55.75,Default,,0000,0000,0000,,so now if I run my test again Dialogue: 0,1:08:55.75,1:08:59.62,Default,,0000,0000,0000,,the error changed Dialogue: 0,1:08:59.62,1:09:02.63,Default,,0000,0000,0000,,so basically it's now using my mock Dialogue: 0,1:09:03.14,1:09:07.45,Default,,0000,0000,0000,,so if I just minimize it again Dialogue: 0,1:09:07.45,1:09:12.10,Default,,0000,0000,0000,,so now it's using my mock Dialogue: 0,1:09:12.88,1:09:17.72,Default,,0000,0000,0000,,and it says that the test expects two trips but it got zero Dialogue: 0,1:09:17.90,1:09:19.68,Default,,0000,0000,0000,,so that's what my test does Dialogue: 0,1:09:19.68,1:09:21.53,Default,,0000,0000,0000,,my test's expecting two Dialogue: 0,1:09:23.56,1:09:26.38,Default,,0000,0000,0000,,so what I need to do is Dialogue: 0,1:09:26.38,1:09:28.04,Default,,0000,0000,0000,,the reason that this is happening Dialogue: 0,1:09:28.04,1:09:31.15,Default,,0000,0000,0000,,because now my production code is using the mock Dialogue: 0,1:09:31.15,1:09:33.01,Default,,0000,0000,0000,,and the mock is not configured Dialogue: 0,1:09:33.05,1:09:37.68,Default,,0000,0000,0000,,so I just need to say that Dialogue: 0,1:09:40.80,1:09:44.48,Default,,0000,0000,0000,,given my trip dao Dialogue: 0,1:09:44.48,1:09:48.57,Default,,0000,0000,0000,,dot trips by user Dialogue: 0,1:09:52.12,1:09:57.81,Default,,0000,0000,0000,,so given that this method is invoked in my mock Dialogue: 0,1:09:59.10,1:10:04.74,Default,,0000,0000,0000,,it will return friend dot trips Dialogue: 0,1:10:04.74,1:10:07.65,Default,,0000,0000,0000,,so what I'm doing here Dialogue: 0,1:10:07.65,1:10:15.62,Default,,0000,0000,0000,,I'm configuring my mock to return the friend trips Dialogue: 0,1:10:15.62,1:10:19.12,Default,,0000,0000,0000,,exactly as the way we've done here Dialogue: 0,1:10:19.12,1:10:21.90,Default,,0000,0000,0000,,I'm doing in here just configuring my mock Dialogue: 0,1:10:21.90,1:10:25.13,Default,,0000,0000,0000,,so now as you can see my test is green Dialogue: 0,1:10:26.62,1:10:31.07,Default,,0000,0000,0000,,so this guy can go back to private now Dialogue: 0,1:10:32.70,1:10:36.72,Default,,0000,0000,0000,,and I don't need this method anymore Dialogue: 0,1:10:38.83,1:10:41.34,Default,,0000,0000,0000,,and if I run all my tests Dialogue: 0,1:10:41.34,1:10:43.31,Default,,0000,0000,0000,,my tests are all green Dialogue: 0,1:10:43.31,1:10:45.78,Default,,0000,0000,0000,,so that means I don't need this class anymore Dialogue: 0,1:10:48.19,1:10:50.95,Default,,0000,0000,0000,,so that means that I don't need this Dialogue: 0,1:10:51.47,1:10:53.97,Default,,0000,0000,0000,,and if I don't need this, I don't need this Dialogue: 0,1:10:54.14,1:10:57.25,Default,,0000,0000,0000,,and in this case, this guy is not been used anymore Dialogue: 0,1:10:57.25,1:10:58.87,Default,,0000,0000,0000,,I can delete Dialogue: 0,1:11:00.16,1:11:01.65,Default,,0000,0000,0000,,so now I can remove Dialogue: 0,1:11:02.38,1:11:04.35,Default,,0000,0000,0000,,I can rename my real trip service Dialogue: 0,1:11:04.35,1:11:05.77,Default,,0000,0000,0000,,because real means nothing Dialogue: 0,1:11:05.77,1:11:07.16,Default,,0000,0000,0000,,so when we're doing test Dialogue: 0,1:11:07.16,1:11:13.53,Default,,0000,0000,0000,,I've seen people calling variable like testee or mock (???) Dialogue: 0,1:11:13.53,1:11:14.95,Default,,0000,0000,0000,,call it what it is Dialogue: 0,1:11:15.79,1:11:20.21,Default,,0000,0000,0000,,it's a trip service. so it should be called trip service, right? Dialogue: 0,1:11:20.25,1:11:22.96,Default,,0000,0000,0000,,so now it's great because Dialogue: 0,1:11:23.89,1:11:27.43,Default,,0000,0000,0000,,I don't have that madness of test double class anymore Dialogue: 0,1:11:27.43,1:11:30.45,Default,,0000,0000,0000,,my test reads quite well Dialogue: 0,1:11:30.94,1:11:34.81,Default,,0000,0000,0000,,and so just make sure that everything is green Dialogue: 0,1:11:34.81,1:11:37.68,Default,,0000,0000,0000,,I can even go there and say Dialogue: 0,1:11:43.52,1:11:45.86,Default,,0000,0000,0000,,so validate logged in user Dialogue: 0,1:11:47.37,1:11:49.13,Default,,0000,0000,0000,,so now as I said Dialogue: 0,1:11:49.13,1:11:53.58,Default,,0000,0000,0000,,I can close all my test methods Dialogue: 0,1:11:55.37,1:12:00.13,Default,,0000,0000,0000,,and we can read this block here and say Dialogue: 0,1:12:00.16,1:12:02.54,Default,,0000,0000,0000,,should throw an exception when user is not logged in Dialogue: 0,1:12:02.54,1:12:05.12,Default,,0000,0000,0000,,that's part of the validation of the logged in user Dialogue: 0,1:12:05.91,1:12:08.91,Default,,0000,0000,0000,,should not return any trips when users are not friends Dialogue: 0,1:12:08.91,1:12:12.82,Default,,0000,0000,0000,,so if the users are not friends returns no trips Dialogue: 0,1:12:13.74,1:12:17.72,Default,,0000,0000,0000,,so should return friend trips Dialogue: 0,1:12:17.72,1:12:18.99,Default,,0000,0000,0000,,when users are friend Dialogue: 0,1:12:18.99,1:12:22.24,Default,,0000,0000,0000,,so if the user is friends with the logged in user Dialogue: 0,1:12:22.24,1:12:24.02,Default,,0000,0000,0000,,just return the trips Dialogue: 0,1:12:28.30,1:12:31.45,Default,,0000,0000,0000,,even this getter method here is not great Dialogue: 0,1:12:31.45,1:12:35.73,Default,,0000,0000,0000,,so get trips by user so that could say Dialogue: 0,1:12:36.24,1:12:39.14,Default,,0000,0000,0000,,get friend trips Dialogue: 0,1:12:39.88,1:12:41.95,Default,,0000,0000,0000,,that sounds much better Dialogue: 0,1:12:42.49,1:12:45.95,Default,,0000,0000,0000,,this guy could be Dialogue: 0,1:12:48.72,1:12:50.67,Default,,0000,0000,0000,,friend as well Dialogue: 0,1:12:51.98,1:12:54.17,Default,,0000,0000,0000,,or something like that Dialogue: 0,1:12:55.97,1:12:59.46,Default,,0000,0000,0000,,so you can play with these things now Dialogue: 0,1:12:59.46,1:13:02.28,Default,,0000,0000,0000,,that you have all the code coverage Dialogue: 0,1:13:02.65,1:13:07.16,Default,,0000,0000,0000,,so basically that's another great point to stop Dialogue: 0,1:13:07.16,1:13:09.23,Default,,0000,0000,0000,,so git status Dialogue: 0,1:13:09.96,1:13:12.33,Default,,0000,0000,0000,,git add . Dialogue: 0,1:13:14.54,1:13:17.50,Default,,0000,0000,0000,,so git commit Dialogue: 0,1:13:19.25,1:13:26.59,Default,,0000,0000,0000,,trip dao injected into trip service Dialogue: 0,1:13:27.80,1:13:30.96,Default,,0000,0000,0000,,so this it it Dialogue: 0,1:13:30.96,1:13:32.46,Default,,0000,0000,0000,,that's normally Dialogue: 0,1:13:33.19,1:13:35.40,Default,,0000,0000,0000,,that's what all the things that you can do Dialogue: 0,1:13:35.40,1:13:37.33,Default,,0000,0000,0000,,with legacy code in a very safe way Dialogue: 0,1:13:39.12,1:13:41.30,Default,,0000,0000,0000,,I can show you Dialogue: 0,1:13:46.73,1:13:50.08,Default,,0000,0000,0000,,I have original trip service somewhere in here Dialogue: 0,1:13:50.12,1:13:53.74,Default,,0000,0000,0000,,so you can compare Dialogue: 0,1:13:53.74,1:14:03.37,Default,,0000,0000,0000,,so we went from this to this Dialogue: 0,1:14:03.37,1:14:05.91,Default,,0000,0000,0000,,and of course that Dialogue: 0,1:14:06.01,1:14:09.43,Default,,0000,0000,0000,,it took me just an hour to do that Dialogue: 0,1:14:09.43,1:14:12.50,Default,,0000,0000,0000,,but it's because I'm recording this screen cast Dialogue: 0,1:14:12.50,1:14:15.86,Default,,0000,0000,0000,,but as soon as you're comfortable with all these techniques Dialogue: 0,1:14:15.86,1:14:19.77,Default,,0000,0000,0000,,this probably would have taken me in a normal day like 20 minutes Dialogue: 0,1:14:19.77,1:14:21.92,Default,,0000,0000,0000,,so it's just like Dialogue: 0,1:14:21.92,1:14:24.34,Default,,0000,0000,0000,,as soon as you're aware of what is available to you Dialogue: 0,1:14:24.37,1:14:25.98,Default,,0000,0000,0000,,then you just practice it Dialogue: 0,1:14:25.98,1:14:29.39,Default,,0000,0000,0000,,and then it makes things much easier Dialogue: 0,1:14:29.39,1:14:32.15,Default,,0000,0000,0000,,and just as a reminder Dialogue: 0,1:14:32.15,1:14:35.24,Default,,0000,0000,0000,,every time that you're working with legacy code Dialogue: 0,1:14:35.24,1:14:40.08,Default,,0000,0000,0000,,your first test should never be the one that goes to the deepest branch Dialogue: 0,1:14:40.08,1:14:42.25,Default,,0000,0000,0000,,always start from shortest branch Dialogue: 0,1:14:42.25,1:14:44.18,Default,,0000,0000,0000,,from the shortest to the deepeset Dialogue: 0,1:14:44.18,1:14:47.00,Default,,0000,0000,0000,,write your test in this order from the shortest to the deepest Dialogue: 0,1:14:47.00,1:14:51.18,Default,,0000,0000,0000,,it's easier because the test will help you to understand what the code does Dialogue: 0,1:14:51.18,1:14:55.30,Default,,0000,0000,0000,,and it will help you to build the test data Dialogue: 0,1:14:55.30,1:14:58.38,Default,,0000,0000,0000,,bit by bit as you dive deep into the code Dialogue: 0,1:14:58.38,1:14:59.98,Default,,0000,0000,0000,,when you're refactoring Dialogue: 0,1:14:59.98,1:15:01.16,Default,,0000,0000,0000,,do the other way around Dialogue: 0,1:15:01.16,1:15:02.91,Default,,0000,0000,0000,,find the deepest branch Dialogue: 0,1:15:02.91,1:15:05.18,Default,,0000,0000,0000,,and start extracting method from there Dialogue: 0,1:15:05.18,1:15:08.42,Default,,0000,0000,0000,,starting put in that behavior into different classes Dialogue: 0,1:15:08.42,1:15:11.40,Default,,0000,0000,0000,,and then all of sudden your code will start Dialogue: 0,1:15:11.40,1:15:14.43,Default,,0000,0000,0000,,collapsing and getting smaller and smaller Dialogue: 0,1:15:14.43,1:15:16.96,Default,,0000,0000,0000,,because you're removing the internal parts Dialogue: 0,1:15:18.60,1:15:23.51,Default,,0000,0000,0000,,so try to write readable and maintainable code Dialogue: 0,1:15:24.04,1:15:25.85,Default,,0000,0000,0000,,try to have the domain language in there Dialogue: 0,1:15:25.85,1:15:27.59,Default,,0000,0000,0000,,try to capture that Dialogue: 0,1:15:27.59,1:15:29.99,Default,,0000,0000,0000,,like using things like guess(???) and stuff like that Dialogue: 0,1:15:29.99,1:15:31.63,Default,,0000,0000,0000,,so as part of the domain Dialogue: 0,1:15:31.63,1:15:36.87,Default,,0000,0000,0000,,try to bring the domain language into your test and into your code Dialogue: 0,1:15:36.87,1:15:42.65,Default,,0000,0000,0000,,the language spoken in the test and the code and used it with your BA should be the same Dialogue: 0,1:15:43.18,1:15:46.27,Default,,0000,0000,0000,,try to have simplicity Dialogue: 0,1:15:46.27,1:15:49.06,Default,,0000,0000,0000,,know your shortcuts, frameworks like Dialogue: 0,1:15:49.06,1:15:51.22,Default,,0000,0000,0000,,try to be fast Dialogue: 0,1:15:51.67,1:15:55.73,Default,,0000,0000,0000,,configure your environment so you can with a few shortcuts Dialogue: 0,1:15:55.73,1:15:57.96,Default,,0000,0000,0000,,create test methods and classes and all sort of stuff Dialogue: 0,1:15:57.96,1:16:00.06,Default,,0000,0000,0000,,and do the refactorings Dialogue: 0,1:16:00.06,1:16:03.56,Default,,0000,0000,0000,,and as I said working in very small increments Dialogue: 0,1:16:03.56,1:16:04.72,Default,,0000,0000,0000,,commit often Dialogue: 0,1:16:04.72,1:16:07.21,Default,,0000,0000,0000,,I mean if you're using git and stuff like that Dialogue: 0,1:16:07.68,1:16:10.40,Default,,0000,0000,0000,,because if you make mistake Dialogue: 0,1:16:10.40,1:16:12.88,Default,,0000,0000,0000,,Ctrl+Z or git reset hard Dialogue: 0,1:16:12.88,1:16:14.83,Default,,0000,0000,0000,,you go back to previous commit Dialogue: 0,1:16:14.83,1:16:16.96,Default,,0000,0000,0000,,and you're back into the green Dialogue: 0,1:16:16.96,1:16:18.68,Default,,0000,0000,0000,,be brave Dialogue: 0,1:16:18.68,1:16:22.02,Default,,0000,0000,0000,,now you know a lot of things like Dialogue: 0,1:16:22.02,1:16:26.90,Default,,0000,0000,0000,,all these small tricks that we learned today Dialogue: 0,1:16:26.90,1:16:31.42,Default,,0000,0000,0000,,we'll make probably 99% of all your classes testable Dialogue: 0,1:16:31.42,1:16:33.17,Default,,0000,0000,0000,,so just be brave Dialogue: 0,1:16:33.17,1:16:35.50,Default,,0000,0000,0000,,use it, and Dialogue: 0,1:16:36.82,1:16:39.76,Default,,0000,0000,0000,,always leave the campground cleaner than you found it Dialogue: 0,1:16:39.76,1:16:41.37,Default,,0000,0000,0000,,so that's the boy scout rule Dialogue: 0,1:16:41.37,1:16:42.71,Default,,0000,0000,0000,,no broken windows Dialogue: 0,1:16:42.71,1:16:44.41,Default,,0000,0000,0000,,if it's smelly Dialogue: 0,1:16:44.41,1:16:47.96,Default,,0000,0000,0000,,if it's not very well written Dialogue: 0,1:16:47.96,1:16:49.09,Default,,0000,0000,0000,,just refactor it Dialogue: 0,1:16:49.09,1:16:50.77,Default,,0000,0000,0000,,just go for it Dialogue: 0,1:16:50.77,1:16:53.14,Default,,0000,0000,0000,,yep, so I hope you enjoyed it Dialogue: 0,1:16:53.80,1:16:55.70,Default,,0000,0000,0000,,that's it Dialogue: 0,1:16:55.70,1:17:00.52,Default,,0000,0000,0000,,so you can find this trip service kata in my github Dialogue: 0,1:17:00.52,1:17:03.84,Default,,0000,0000,0000,,so just go to github sandromancuso trip service kata Dialogue: 0,1:17:03.84,1:17:05.62,Default,,0000,0000,0000,,that's it, hope you enjoyed it Dialogue: 0,1:17:05.62,1:17:07.48,Default,,0000,0000,0000,,thank you