Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tomek Kaczanowski - Practical Unit Testing with JUnit and Mockito - 2013.pdf
Скачиваний:
224
Добавлен:
07.03.2016
Размер:
6.59 Mб
Скачать

Chapter 5. Mocks, Stubs, Test Spies

has a ripple effect on your tests, with many of them then needing to be changed14. Thirdly, it obliges you to develop classes in some specific order (e.g. the Phone class must be ready and fully tested before you can start working on the Client class), and may lull you into being over-reliant upon the existing implementation of the collaborators.

On the other hand, using test doubles in some situations might be considered overkill. For people who are new to test doubles, writing new MyClass() instead of mock(MyClass.class) is much more natural, especially if there is no instant gain in using test doubles.

In general, I would recommend using test doubles. The overheads related to their creation and the setting of expectations might seem unjustified at first (especially if a collaborator is very simple). However, when the design of your classes changes, you will benefit from the isolation, and your tests will not break down unexpectedly. Also, current frameworks only call for you to write a very small number of lines of code, so there is no decline in productivity. Using a test double makes it virtually impossible to rely on the DOCs’ implementation, as it might not exist yet.

The only situations where I would consider using a real collaborator instead of a test double are the following:

the collaborator is very, very simple, preferably without any logic (e.g. some sort of "container" class with only accessors and mutators methods),

the collaborator’s logic is so simple that it is clear how to set it in the desired state (and its logic will not be enhanced in the foreseeable future).

Even then, I would be highly cautious, as changes are inevitable – no matter how very unlikely they may seem!

5.6. Conclusions (with a Warning)

In this section we have discussed an essential – and probably the hardest – part of unit testing. We have learned about the various types of test double, and started using Mockito to create and manage them in tests. Working with an example has enabled us to acquire an overview of what it is like to develop tests using the TDD approach with test doubles. Wow… really a lot of knowledge this time!

By introducing test doubles, and especially test spies, we have entered the realm of interaction testing. Thanks to them, we can test much more than we would be able to with state testing alone. This is definitely a good thing. However, there is always a price to pay, and this is indeed the case with test doubles. So before we start putting our new testing abilities to use, we really ought to try to become aware of the perils awaiting us.

In fact, we are in a trap, even if we have not yet seen it. The problem is as follows: as we already know, if we just stick to state testing, we will not be able to test everything (as discussed in Section 2.2.1). However, if we start testing interactions between objects, we will soon discover that even innocent seeming refactorings may result in broken-down tests. And why is that? Well, with state testing all we attend to is the outcome (of some method calls), and this gives us the freedom to refactor the tested code. With interaction testing things are different, because it is all about methods being called on collaborators.

14Another solution is to extract the DOCs creation parts of the code into some utility method. This solves the problem of multiple changes, but reduces the readability of test code by forcing the reader to jump between different classes.

94

Chapter 5. Mocks, Stubs, Test Spies

Interaction testing makes some assumptions about the implementation of an object, and thus makes it harder to change this implementation.

We can think about this using a black-box/white-box analogy. With state testing, the SUT is a black box. We put some things inside, and verify what comes out. State testing respects objects’ right to privacy, and does not try to make any assumptions about "how" things work inside. It concentrates only on "what" the results of actions amount to. With interactions testing the focus changes from "what" to "how". The SUT is no longer a black box. On the contrary, we look inside the SUT (contravening the "information hiding" principle15, along the way), and verify its internal parts. And, as usual when breaking some sensible rules, we pay a price for this.

We will discuss issues pertaining to the manageability of tests as these relate to interactions testing in Chapter 11, Test Quality.

15See http://en.wikipedia.org/wiki/Information_hiding

95

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]