Testing With Our Test Context9:16 with Chris Ramacciotti
In this video, we leverage the test context we created in the previous video and begin writing the tests for a service that accesses an external API.
Sync Your Code to the Start of this Video
git checkout -f v8
Using Git with this Workshop
See the README on Github for information on how to use Git with this repo to follow along with this workshop.
With our test contacts ready to rock, let's get to writing these tests. 0:00 The first thing we'll do is Autowire our service under test that is 0:04 the Weather Service. 0:08 So I'll create an Autowired field here Weather Service, and I'll name it service. 0:09 Next, let's tell about our test methods. 0:17 Now, we could go crazy testing the service that utilizes the external forecast at 0:20 IO API. 0:24 Here, we'll just test a few pieces of the actual API response. 0:26 First, we'll make sure that the latitude and longitude that come back 0:30 from the API response match what we included in the request. 0:32 The reason I'm doing this is because I want to make sure that the forecast data 0:36 I'm getting back is actually for 0:39 the location I requested and not some other location. 0:40 So, here's that method stub. 0:44 We'll say it's a test method. 0:46 Public void, and we want to test if 0:48 findByLocation_ShouldReturnSameCoords. 0:53 Next, let's make sure we get back eight days of forecast data. 1:02 So next, I'll right a test method that's called findByLocation, and 1:06 it should return 8DaysForecastData. 1:15 Now, that's today and the next seven days. 1:22 Cool. 1:28 And finally, 1:30 let's make a test that ensures we can get back our current conditions. 1:31 So, this test method, will be called public 1:35 void findByLocation_ShouldReturnCurrentCondit- 1:40 ions Great. 1:46 Now keep in mind that the purpose of these tests isn't so 1:51 much to ensure that the weather API works, that's for the developers of that API. 1:54 Rather this is to ensure that our application properly 1:58 captures those results and sticks the results into the proper objects. 2:01 Okay, that said, let's start in on the first method. 2:06 So that should be the findByLocation_ShouldReturnSameCoords. 2:10 Since we'll need a set of latitude and longitude coordinates to make these 2:14 requests, let's create a field for that and set it up in the before method. 2:18 So right here, I'll say private Location and abbreviate it loc. 2:22 Of course the wild thing to do would be to name it Tone Loc. 2:29 Anyway let's import this and go here hit option enter and 2:33 want to make sure I pick my object right here. 2:38 There it is cool. 2:42 And let's create a before method to set that up. 2:44 Before. 2:47 So public void set up sometimes you'll see this U capitalized. 2:49 Doesn't really matter as long as it's annotated with before. 2:54 And we'll say loc = new Location and you can pass in whatever coordinates you like. 2:57 I've got a set of coordinates that point to Chicago, somewhere in Chicago at least. 3:04 9403795. 3:10 And -87.6531804 and 3:15 then a bunch of 9's. 3:21 Cool, and as we're fetching the data, 3:27 we're going to get back a weather object so let's create a field for that and 3:28 make the service call that stores a weather object into it. 3:31 So the field, I'll make right here private Weather weather, 3:34 and I will make that service call right here. 3:39 Since in all of these tests I'm going to be making a call to that find by location 3:44 method of the service. 3:48 So I'll say, weather = service.findByLocation and 3:50 I'll pass it loc or Tone Loc, whatever you named it. 3:54 Now, to test the coordinates in the test method, I'll use Hamcrest and 4:00 test the latitude and longitude separately. 4:03 So in here I will assertThat and we'll say that the weather.getlatitude and 4:06 let's get that assertThat method imported here and 4:13 that comes from hamcrest right here. 4:19 Cool. 4:22 I want to assert that weather.getlatitude 4:22 is close to the latitude that I made the API call with. 4:27 Now since geo coordinates may not be exact, 4:32 we can use a handy hamcrest matcher called close to. 4:34 That checks whether or not the actual value is close to an expected value 4:38 within a specified margin of error. 4:42 And since I'll be reusing this margin of error for longitude, 4:44 I'll quickly create a class field for that. 4:46 So up here, I'll say private static final double. 4:48 I'll call it ERROR_GEO. 4:55 Zero point, I don't know, I'll make it a reasonably precise value. 5:00 And now here's how we use that CloseTo method. 5:06 So, I'll say, closeTo, okay, 5:11 loc.getLongitude, ERROR_GEO. 5:16 Okay, now we need to import this closeTo method. 5:23 So, that's a static import of the matchers.closeTo method and there we go. 5:25 We want to assert that this latitude that we get back in the weather object which is 5:32 a result of the service call, we want to assert that the latitude is closeTo 5:37 the longitude we made the call with within this margin of error. 5:44 Of course, we wanna check latitude with latitude. 5:49 So I should probably change this to latitude. 5:51 Cool. 5:53 Now let's copy and paste this for longitude. 5:55 So I'll copy this and I will paste this, changing it to longitude. 5:57 All right, let's see if this thing runs with our test context. 6:06 So, again, with the editor in focus, I'll hit control, shift, R. 6:08 Now, you'll see a little more output this time as spring loads only 6:13 the specified components from your test context. 6:16 And, great. 6:19 Still green. 6:20 Next test. 6:22 Let me collapse this. 6:23 And in our next test, let's assert that 6:26 we get eight days of forecast data. 6:30 So we want to assert that when we get the daily forecast data, 6:35 that this list has the size of eight. 6:41 Lots of stuff you can do with these Hamcrest matchers. 6:47 Again, these matchers are really nice in that you can create some 6:50 cool readable code here. 6:53 So we're going to assert that this list has this size. 6:55 Okay, let's run that again. 7:01 Again, you'll see a lot of output from your test context being loaded and 7:05 it looks like indeed our second test passed on to the last method here. 7:10 For this one, we wanna make sure that the data we get back is time stamped with 7:17 the current time within a reasonable margin of error. 7:20 Let's create a field for that error margin too, 7:23 and this one will be expressed in milliseconds. 7:25 So, I'll go right below this one, and I'll say private static final 7:28 double ERROR_TIME this time. 7:32 And again it's in milliseconds. 7:37 So, say as long as it's in within five seconds then I'll be cool with that. 7:38 Now the way will do this is that will first grab the current time 7:43 as an instant object. 7:46 So we’ll say instant. 7:48 I'll call it now equals Instant.now. 7:50 Excellent. 7:53 Then we'll calculate the duration between that instant and 7:54 the instant from the weather data returned by the service. 7:58 So let's create a variable for that. 8:01 So the duration will say as duration.between. 8:03 We'll say it's between now and 8:08 weather.getCurrently().getTime and 8:11 we will convert that to milliseconds, toMillis(). 8:17 So we're going to get the duration between now and 8:23 whatever time stamp comes back expressed in milliseconds. 8:27 Storing that into the double variable we have named duration. 8:31 And finally, we will assertThat the duration, again using this closeTo method, 8:35 the duration is close to 0 within this margin of error. 8:42 All righty, with our final piece of test code written for 8:48 the weather service, let's fire it up one more time. 8:51 Our test contacts loading and it looks like all three tests passed. 8:56 Boom, hey we're seeing a lot of green today, but 9:02 I guarantee you that the grass isn't always this green. 9:04 There might be a lot of red as you try to get these working on your machine, 9:08 whether it's for this project or for another. 9:11 But hey keep at it. 9:13 You'll eventually get there. 9:14
You need to sign up for Treehouse in order to download course files.Sign up