Testing Services10:04 with Chris Ramacciotti
Moving one step closer to the database, in this video we start testing our services. For some tests, this involves mocking DAOs.
Sync Your Code to the Start of this Video
git checkout -f v6
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.
Getting Started with Hamcrest
Now that you've seen some ways you can unit test controllers, 0:00 it's time to take a step towards the database into services. 0:02 Let's start by testing the favorite service. 0:06 Now because the favorite service depends on the favorite DAO and 0:08 we don't want to test the DAO here, we'll need to mark the DAO. 0:11 So let's create that test class now. 0:16 You can use IntelliJ to do that from the favorite service, or 0:18 you can simply create it in IntelliJ manually. 0:22 So I'll create a package here, and I'll name it com.teamtreehouse.service. 0:27 Cool and in that service class, I will add a favorite service test. 0:33 So, New Java Class FavoriteServiceTest. 0:38 Excellent. 0:45 In this class, we'll include one, test for the services find all method and 0:47 two tests for the services find by ID method. 0:50 One for a favorite that is found, and one for a favorite that isn't found. 0:53 Let's step out those methods now. 0:56 So we'll start with a test. 0:59 Let's import that from J Unit. 1:03 So we'll start with the test of the FindAll method. 1:05 So public void FindAll_ShouldReturnTwo. 1:09 We'll say that it throws an exception. 1:15 And then for the two findById methods. 1:19 So we'll say, test public void findById, 1:23 this one should return one favorite object 1:28 and then the next findById method. 1:36 So test public void findById. 1:38 This one should throw favorite not found exception 1:42 throws exception. 1:48 Okay just as we've done for the controller test. 1:55 Let's set up Mockito for use in this class. 1:59 So here I'm going to runwith. 2:02 Mockito's JUnitRunner, so MockitoJUnitRunner.class, cool. 2:05 And as a couple fields here, we're going to need a DAO that will mock and 2:12 the favorite service that is under test. 2:16 So we're going to be mocking that DAO, so private favorite DAO and 2:19 favoriteDAO; make sure to import that class, cool. 2:26 And I'm going to @InjectMocks into the service. 2:32 So private FavoriteService and I'll call it service. 2:39 Now, since the favorite service is not an interface, 2:48 it can't be instantiated directly so we'll need to take care of that for Mockito. 2:51 So new FavoriteServiceImpl. 2:56 Okay, I'm gonna rename this field dao, 3:00 to keep my naming simple here since I already know it's the favorite service so 3:02 obviously we are leveraging favorite dao here. 3:06 If you had multiple dao fields here, you would certainly wanna tack on the model or 3:09 domain object to that dao service is handling. 3:13 Now unlike the controller test, there's nothing to set up in addition to what 3:18 Mockito is going to take care of for us, so we won't need a before method here. 3:21 So let's head to that first test right here. 3:27 We'll start by mocking the DIO to return a list of two favorites when it's 3:31 find all method is called, so I'll create a quick list. 3:35 So this will be a list of favorite objects. 3:38 I'll call it faves. 3:42 And I'll say Arrays.asList. 3:44 And let's keep this simple. 3:47 Let's just make a couple favorite objects with nothing, Or at least 3:49 no details included in them, since I'm not going to actually test the details. 3:56 Next, will configure the mock DAO to return this list 4:01 when its find all method is called. 4:04 So, will say, when the favorite DAO, 4:06 the dao.findAll method is called, cool. 4:12 We will return faves. 4:16 Now I'm not getting the auto completion here because I haven't imported this, 4:20 so I'll hit Option Enter on a Mac to auto import that. 4:24 Cool. 4:30 And next I'll use a standard J Unit assertion to confirm that a list of 4:31 two items is returned by the services find all method. 4:35 So you should be familiar with the assertEquals method. 4:39 And we'll first place our message in here, 4:44 "findAll should return two favorites", 4:48 And the expected value is 2. 4:54 And the actual value will be service.findAll.size. 4:57 Cool, and again do a static import of that a cert equals from org.J Unit. 5:06 Excellent. 5:14 Now we should verify that the dao's find all method was indeed called. 5:15 So let's do that as well, so we will verify. 5:19 So Mockito.verify, that the Dao's find all method was indeed called. 5:23 Let's check it out. 5:30 We are ready to run these tests with control shift r. 5:31 All right look and good. 5:37 Moving on to the next test method. 5:38 The first find by ID method right here. 5:40 I'll show you another way to assert results in this method, 5:46 we'll start though by marking the DAO to return 5:53 a favorite object when the find by ID method is called. 5:58 So we use that same approach when The (dao.findOne (1L)).thenReturn(new 6:04 Favorite ()); use it's default constructor. 6:10 Again I'm not really concerned here about the details of the favorite object, 6:16 just that what the DAO returns is indeed a favorite object. 6:18 Now instead of using J units assert methods with say assert not null, 6:22 we can use the ham cress libraries assert 6:26 that method which provides nicely readable intentional assertions. 6:29 Check it out. 6:34 I can say assertThat and this comes from ham crest right here. 6:36 I can say assert that the service findByID method 6:41 called with 1, assert that that returns 6:46 an instance of Favorite.class. 6:51 Okay, and we want to static import this from the ham crest library. 6:59 So, we want matchers.instanceOf right there, cool. 7:06 One nice thing, a lot of developers like about the ham crest assertions, 7:10 is that the actual value comes before the expected value, 7:13 that is this is the actual value This is the expected value as 7:17 opposed to J unit assertions where the expected value comes first and 7:22 the actual value comes second. 7:27 Many developers, including myself, think that this hand press version, 7:31 that is the assert that, reads more naturally. 7:35 Like assert that this value is an instance of this 7:39 object that's a nicely readable sentence our code reads just like a story. 7:44 Check the teacher's notes for more on ham crest. 7:51 For now, let's close out this test by verifying that the DAO's find one method 7:53 was indeed called. 7:58 So I will verify that the dao).findOne() 7:59 method was called, with 1 as an ID. 8:05 Okay let's run this test. 8:09 Hey once again, we're in the green. 8:13 Now as for our last test in this class, 8:16 we want to check the service's findByID method to make sure it throws 8:18 a favor not found exception when the dao returns a null value. 8:21 So let's first mock the DAO to return null. 8:26 So I'll say when the dao's .findOne() method is called, 8:32 with 1 as the ID, let's return null. 8:38 Now, in contrast to the controllers handling of this exception, in the case of 8:44 the service, the exception will actually bubble up to our test method. 8:49 So we can use that familiar expected element on the methods test annotation, 8:53 like this. 8:57 Expected equals FavoriteNotFoundException.class. 8:59 Now, to trigger the exception, well, hopefully trigger it, 9:06 we need to call the services, find by ID method, so, let's do that. 9:09 service.findById, passing it a 1, as the ID. 9:13 And to verify, that the DAO's, 9:18 to find one method was actually called, let's call the verify method. 9:20 Verify that the dao's find one method was called with a value of 1. 9:25 Now, when we test the exception should be thrown and 9:30 since it's an expected one right here, 9:35 the test is expected to include an exception called favor not 9:37 found exception Since that is the case we should have a passing test here. 9:42 But let's run it to make sure that it is indeed the case. 9:47 Control shift R to run and looks like all three tests have indeed passed. 9:50 Now with some service test written, 9:56 next we'll move on to testing the weather service. 9:58 Which involves a set up that's a bit more complicated. 10:00
You need to sign up for Treehouse in order to download course files.Sign up