Now, I'd like to talk to you about test doubles for output, and these are called Mocks and Spys. If you do a Google search for quotes involving mocks, it turns out you find thousands of them. Because there are so many, I thought I'd add my own. So, if you mock my class, I hope you're testing. But let me just put mocks in context. What we're looking at is test doubles. So, we have a system under test that we want a unit test, it uses other systems. Sometimes those other systems aren't available or are too expensive to use or are owned by somebody else, and so we create dummy objects that allow us to create things that stand in for those other systems while we're testing the system that we actually care about. So, we have Dummy Objects, Test Stubs, Fake Objects, these are all inputs to the system, and then we have Mock Objects and Spy Objects, and these allow us to do fine-grain monitoring of the system under test. So, they're not providing inputs but they're providing monitoring capabilities. What do I mean by that? Testing is more than checking the function outputs. So, a lot of times, we're trying to test methods that may return void, so there's nothing to check. Instead, what we want to check is interactions. In some cases, are methods call in the proper order? Are they called with the proper parameters? Are they called too many times or too few times? And mock objects and spy objects allow us to observe these interactions. So, mock objects allow us to observe interactions using these fake objects that we've constructed using Mockito. Spy objects allow us to wrap real objects in Mockito to observe the interactions with the system under test and those objects. So, now let me go over to the clips and demonstrate for you. Okay. Here we are back with the employee travel service. What we'd like to do is we'd like to check that it interacts correctly with the AirlineTravelService. So, we have our EmployeeTravelScheduler that basically calls out to the AirlineTravelService and does some manipulation to determine which flights an employee should take when taking business trips. But we want to make sure that it uses this AirlineTravelService correctly because if it does it wrong, then maybe we end up double booking flights or we end up not getting the right flights or many other things. So, what we'd like to be able to do is not just check the output when we asked the service to find flights, but we'd also like to check that its interactions with the AirlineTravelService are correct. So, what we do is we mock our AirlineTravelService. We create a stub, actually. So, this is an example, this test case is an example where we have one object that's being used as both a stub and a mock. So, we're going to stub it, in terms we're going to create some fake flights that the travel service can return, and we're going to look at its interaction with the system under test, which is the EmployeeTravelScheduler, and that's going to be a capability of mocking. So, what we do is we create some flights, and we're going to have a capability that the travel service has to confirm flights. So, basically, when the EmployeeTravelScheduler works with the AirlineTravelService and the employee wants to book a flight, it's first going to confirm that the flight is available, and if it's available, it's going to book it. So, we have two flights. If we try and confirm the first one, the stub is going to return true. If we try and confirm the second one, the stub is going to return false. Then, what we want to do is we want to check a couple of things. First, we want to check to see the outputs of the call that we made. So, we should be able to book the first flight because it's confirmed that it's available, but not the second flight. So, we have these calls, and these just check the return values as you would expect. But we're also going to check the interactions that the EmployeeTravelScheduler had with the AirlineTravelService. The way that we can do that is we can verify using Mockito that certain methods were called, and how many times they were called. So, what we say here, this is where the mocking comes in, we verify that on that stub service we created twice the confirmFlight() method was called for any flight. So, what this is allowing us to do is when we ran this test, it allows us to check afterwards how many times did the system under test interact with this class that we constructed. So we want to make sure that we confirmed the flight twice, so we check the flight confirmation for both the successful case and the failure case. When the flight wasn't confirmed for the second case, we didn't want to book it. So, we should have, as the proper interactions, is two times calling confirmFlight() and one time calling bookFlight(). So, we have two different verify calls here that allow us to check these interactions. When we run the test cases through using the mocks and stubs, we can see that in fact that is the number of times that our stub service confirmed the flight. So let's see. This should fail now because it doesn't call this stub service three times or confirmFlight() three times, there's only two different flights that it checks. So, this call should fail, and we'll try it out. And sure enough, it does fail. So, one thing I haven't done is shown you in the case of failure, we can see if we look down this tree view that one of the tests failed, and we can look and see. Sure enough, it was testBookFlight. But there's not any more information here, and we can right-click and get more information and determine what the failure was. So, in this case, the failure was TooLittleActualInvocations. So, we said it should call that confirmFlights() three times, and it only called it twice. So, it'll tell us exactly where the failure was, and that's pretty good information that we can get out of this. It turns out that Gradle also produces reports. Okay. So, here is our travel system project that we've defined in Eclipse. If we look inside it, when we use Gradle it actually builds some folders inside of our project, one of them is called "build", and we can look at reports and look in tests. If we look here, we can actually get an HTML report on which tests passed and failed. So, we can look here and see that we have 90 percent successful in terms of tests. It'll tell us information about the different packages that we had in our project and the different classes. So, we can look at the information and testing in several different ways. But if we look at the EmployeeTravelSchedulerTest, what we'll see is, we can either look at all the tests or we can just look at the failed test. If you look at the testBookFlight, we'll see the same information that we saw when we right-clicked on the Gradle tab button here in an HTML report form. So, it's really quite nice in terms of giving you status and information about the project. So, let's turn that back to 2. One thing that we did here, is that we didn't actually care about what the order of methods in terms of when they were called was. Sometimes, it's not enough to know the number of times that a method was called. But we also want to know the order in which methods were called, and we can do that with Mockito as well. So, the way that we do that, is we use a class that's defined by Mockito called InOrder. So, we declare a new one of these guys and then we instantiate it on the stub-class that we have. So, we have our stub service here and we pass that in to construct a new InOrder object. Then, what we can do is, we can verify. When we call verify() on that, what it'll do is it'll check that those calls to verify are in order. So in this case, we have only one call the bookFlight() in that call is successful. So, the interactions that the employee travelers scheduler should have with the airline travel services that it should call confirmFlight() and then it should call bookFlight() afterwards. So, we can confirm the order in which these things are called, by doing this InOrder.verify. So, we say first thing that should happen is, we get a confirmFlight() involving some flight. Then, we're booking the particular flight, "f1" with a particular payment method. So, this describes the interactions in the order that we expect on the flight. So, let me run this, and everything should work. But now, I'm going to change the order, I'm going to put the bookFlight() in front of the confirmFlight(), and this should fail, because we should never book a flight before checking its confirmation. And sure enough, it does. So, when we look at the failure result, if we right-click and show failures. All right, this time, it just tells us to go look at the report. It's because I didn't quite get specific enough. Sometimes I like looking at the HTML reports better than I like looking in this tree view, just because I know where to look. So if we look, what we see is a verification in order failure. So, wanted but not invoked was confirmFlight() and instead what we had was, we had bookFlight(). So, this InOrder class is checking that we're not only calling the right number of times into a method, but we're checking that the order is the right order. So, that's how we can do these mocks. All right. Now, I'd like to talk to you about spies. So, spies are a way of inspecting the interactions with real objects rather than these mock objects we've created. So, this is kind of an amazing capability. You can take any object that you've constructed and wrap it in a spy, and then you can interact with it as normal. Afterwards, you can see how those interactions worked. So in this test example, we have a spy that is going to spy on this ArrayList that we construct for containing the flights. This is kind of a trivial example, but you can do much more interesting things with it. So, we can interact with our list as usual, add things to it just like we were dealing directly with the ArrayList. Then, we can run one of our tests as we do, that finds the appropriate flight. But then, we can verify, for example in this case, that we call add() on this list twice. Of course, we're doing it as part of the test. So, this is kind of a trivial example. But you can construct much more complex examples, where you pass in a parameter to the system under test and then you can examine the system under test interaction with it even if it's a real object. So, when we run this test, we can see that it passes and if I change the number of times, then it'll fail just like on the mock object that we saw before. But the interesting thing there is that, now we're dealing with a real object rather than a fake one. So, that's all I'd like to talk about for mocks and spies. But there are a lot of capabilities that you can do that go beyond what we've talked about in this lesson. For example, a spy, you can override the behavior of methods just like you can with a stub. You can do the same kinds of things with the spy that you can do with a stub object. So, if I want the ArrayList to return something special when I call get() on a particular cell, I can do it. So, if you're interested in learning more about this, I would encourage you to go out to the Mockito site and read about all the capabilities of Mockito.