Chapter 4. Stubbing Behavior of Mocks

In this chapter, we will cover the following recipes:

  • Using argument matchers for stubbing
  • Stubbing methods that return values
  • Stubbing methods so they throw exceptions
  • Stubbing methods so they return custom answers
  • Stubbing methods so they call real methods
  • Stubbing void methods
  • Stubbing void methods so they throw exceptions
  • Stubbing void methods so they return custom answers
  • Stubbing final methods with PowerMock
  • Stubbing static methods with PowerMock
  • Stubbing object instantiation with PowerMock

Introduction

As explained in the previous chapters, Mockito is all about creating mocks and stubbing their behavior. It's worth taking another look at the differences between mocks and stubs in order to properly distinguish possible actions that can be taken on either of them. In his xUnit patterns (http://xunitpatterns.com/Test%20Double%20Patterns.html), Gerard Meszaros describes stubs and mocks as follows:

  • Stub: This is an object that has predefined answers to method executions made during the test
  • Mock: This is an object that has predefined answers to method executions made during the test and that has recorded expectations of these executions

Mockito does not distinguish this separation, so each test double, regardless of its purpose, is considered to be a mock. This chapter will focus on showing you numerous ways of the stubbing behavior of mocks in order to simulate real interactions. We'll cover stubbing methods that return values and those that are void. We'll simulate returning results, throwing exceptions, and execution of custom logic. We'll also go down the path of dealing with static, final method, and object-initialization stubbing. (Hopefully you'll never need to use stubbing. Otherwise it means that something is wrong with your code or you're integrating it with some third-party piece of software that does not follow object-oriented principles.)

Before going further, let's take a closer look at two definitions: behavior of the application and its interactions.

Your system should be split into modules that have limited responsibilities. These responsibilities may be related to some computation, data storing or processing, and so on. You can compare the behavior to the outcome of these actions, so when you're testing the behavior, you will mostly be interested in whether your system has altered the input data or stored some values and not in how it was done (for instance, a particular method was executed). Often, it might not even involve a mock—you just want to test the output for the given input. (If you are writing a piece of software that adds two numbers, then why would you want to mock any collaborators? Just check whether by providing 1 and 1 as arguments, you get 2 as the result.)

Interactions are concrete calls between different parts of your system. In Chapter 6, Verifying Test Doubles, I will describe with greater depth the situations in which it is worth checking whether some particular piece of code was called. It's all about a sense of security and the business requirements.

In the forthcoming recipes, we will not verify interactions. Instead, we will verify whether the system under the test's logic does what it is supposed to do. You might ask why we are not performing such verifications on the mocked object. The reason is that what we want to test in the aforementioned examples is not whether a method has been called on a mock but whether the logic that was executed by the system under test works as we expect it to work.

Imagine that you change some algorithm inside the collaborating object but at the end of the day, you want the system under test to work in exactly the same manner. If you test your implementation and not the behavior, your test will fail. In other words, in the majority of cases, you don't want to know exactly how something is done. Instead, you want to know what its outcome is. You can check the Google testing article at http://googletesting.blogspot.com/2013/08/testing-on-toilet-test-behavior-not.html to see nice examples of why you should be interested in it and not how your system under test does what it is supposed to do.

Note

If possible, verify the behavior and not the implementation.

While going through the examples in this chapter, you will see that there is some repetition and similarity of content. This is done on purpose to make the examples look alike so that the reader memorizes them fast. Since this is a cookbook, it is written in such a way that each recipe can be addressed separately in terms of the examples and solutions. This is why I always want to give you the business background of the tested system. You will not always read this book chapter by chapter. You might want to find a particular solution to your problem and then you wouldn't have to search through the book to check whether the system under test looks like some other system.

Note

The following is a standard reminder that you will see throughout the book:

As I am very fond of the Behavior Driven Development in all of the test cases, I'm using Mockito's BDDMockito and AssertJ's BDDAssertions static methods to make the code even more readable and intuitive. Also, please read Szczepan Faber's blog (the author of Mockito) about the given, when, then separation in your test methods; http://monkeyisland.pl/2009/12/07/given-when-then-forever/, since these methods are omnipresent throughout the book.

Even though you might not understand some of the preceding explanations, or the test code might look complicated, don't worry as it will all get explained throughout the book. I don't want the book to become a duplication of the Mockito documentation that is of high quality. Instead, I would like you to take a look at nice tests and get acquainted with the Mockito syntax from the early beginning. What is more, I'm using static imports in the code to make it even more readable, so if you get confused with any of the pieces of code, it would be best to refer to the repository and the code as such.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.114.28