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

Part II. Writing Unit Tests

Chuck Norris doesn’t need unit tests because his code always works. ALWAYS.

— Wisdom of the Internet ;)

If there is a technique at the heart of extreme programming (XP), it is unit testing.

— Kent Beck Extreme Programming Explained: Embrace Change (1999)

In a way, the phrase "unit test" is kind of misleading – it’s really more akin to forcing yourself to use your own code like another developer or user would… and taking off those developer blinders for a moment.

— Jeff Atwood

A test is not a unit test if:

It talks to the database

It communicates across the network

It touches the file system

It can’t run at the same time as any of your other unit tests

You have to do special things to your environment (such as editing config files) to run it.

Michael Feathers A Set Of Unit Testing Rules (2005)

Chapter 3. Unit Tests with no

Collaborators

It is really fun to understand the types of interaction and parts of unit tests, but since "practice makes perfect" it is high time to put this knowledge to use. Just for now, we will be concentrating on a subset of testing issues, assuming as we shall that our SUT does not need any collaborators. This assumption

– even if it does not hold for the majority of real-life classes – will permit us to demonstrate some important concepts, ideas and techniques. They will be much easier to explain under such conditions, even though their use is by no means limited to a no-collaborators environment. In fact some of them – e.g. the TDD approach – are not even confined to unit testing itself.

In later sections (starting with Chapter 5, Mocks, Stubs, Test Spies) we drop this unrealistic assumption and discuss techniques for testing an SUT which cooperates with collaborators in various ways. But for now, let us pretend that our SUT is all alone.

After reading the tools introduction you will already know that JUnit is the most popular Java testing framework aimed especially at unit tests. In this section we will learn to write and execute JUnit tests, and also learn some JUnit features that will be reused throughout the book. Some of them will only be briefly mentioned here, prior to being discussed in more detail in subsequent chapters.

This book is not an all-embracing JUnit tutorial, even though it contains everything you should know if you want to write high-quality unit tests. JUnit offers more than is described here, including some features useful for integration and end-to-end tests. To truly master this tool, you should refer to other resources, i.e. JUnit documentation.

3.1. Project Structure and Naming

Conventions

Java developers tend to use similar layout for their projects these days. All sources of production code commonly reside in the src/main/java directory, while all test source files are kept at src/test/java.

Below, you can see an example of a typical project layout:

Listing 3.1. Typical project layout

`-- src

|-- main

|

`-- java

|

`-- com

|

`-- practicalunittesting

|

`-- Money.java

`-- test

`-- java `-- com

`-- practicalunittesting |-- MoneyTest.java

src/main/java is where all your production code is located, an exemplary production class - Money,

19

Chapter 3. Unit Tests with no Collaborators

src/test/java is where all your test code resides, an exemplary test class - MoneyTest.

The main thing to notice is that code and tests reside in different subtrees. This way your production JARs will not be polluted with unnecessary test classes. Most tools (that I am aware of) recognize this layout, and will treat both subtrees accordingly.

You probably have also noticed that test classes follow the SomethingTest name format (in our case, here, it is MoneyTest). The Something prefix will usually be the name of a class being tested by this particular test. This is a very common pattern, definitely worth following, as it enables developers to understand at once which class is being tested. Some tools also take advantage of this naming format1.

We will be following this layout and naming format throughout the book.

3.2. Class To Test

For our first unit-testing experience we will use a Money class, almost identical to the one used in a popular unit testing tutorial from JUnit2. For unit testing, the Money class plays a similar role to that played for any programming language by the famous HelloWorld example: it just has to be there3. ;) We will begin with a very simple (and, to be honest, quite useless) class. Later on it will be extended.

Listing 3.2. Money class to be tested

public class Money {

private final int amount; private final String currency;

public Money(int amount, String currency) { this.amount = amount;

this.currency = currency;

}

public int getAmount() { return amount;

}

public String getCurrency() { return currency;

}

public boolean equals(Object anObject) { if (anObject instanceof Money) {

Money money = (Money) anObject;

return money.getCurrency().equals(getCurrency()) && getAmount() == money.getAmount();

}

return false;

}

}

As you can see, the Money class is immutable. It has two final fields set by the constructor. The only method with some logic is the implementation of equals().

1For some discussion of test-naming approaches, please refer to Section 9.2 2See http://junit.sourceforge.net/doc/testinfected/testing.htm

3This reminds me of the first time I put to the test the examples from this tutorial. It took me a few weeks to really digest these ideas about unit testing, which were completely new to me back then.

20

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