JUnit is a unit testing framework for the Java
programming language. JUnit has been important in the development of
test-driven development, and is one of a family of unit testing frameworks
collectively known as xUnit that originated with JUnit.
we'll define a unit test as a test of a single
isolated component in a repeatable way. Let's go thru that one section at a
time to get a clearer idea of what goes into a unit test.
"a test". This means to verify something
is correct. In order for us to have a valid unit test, we need to actually
validate that after a start condition A, an end condition B exists. "...a
single isolated component...". This is what separates a unit test from
other types of tests.
In order for
it to be a unit test, it must test something in isolation, aka without
dependencies. The reason for this is that we are testing the component itself
and not it's interaction with other components (that is an integration test).
Finally, although most definitions don't include
this piece, "...in a repeatable way" is a very important piece of the
definition. It's one thing to run a test that passes. It's quite different to
have something you can run in a repeatable manor at any point to see if changes
you made effected how the component behaves. For example, if you choose to do
some refactoring to improve performance, can you rerun your unit test to verify
that you didn't change the behavior of the component.
In test driven design, we develop the unit test
before the functionality. We write a test that verifies that the class should
do X after our call. We prove that the test fails, we then create the component
to make the test pass. In this case, we are going to create a service with a
method that authenticates a user. Below is a class diagram of the scenario.
JUnit
class diagram
The
interfaces
We will start our coding by defining two interfaces,
LoginService and Userx We will implement LoginService, For LoginService, we
have a single method that takes a String userName and String password and
returns a boolean (true if the user was found, false if it was not). The
interface looks like this:
Provides authenticated related processing.
public interface LoginService {
Handles a
request to login. Passwords are stored
as an MD5 Hash in
this
system. The login service creates a hash
based on the paramters
received
and looks up the user. If a user with
the same userName and
password
hash are found, true is returned, else false is returned.
boolean
login(String userName, String password);
}
The Userx
interface will look very similar to the LoginService. It will have a
single method that takes a userName and hash. The hash is an MD5 hashed version
of the password, provided by the above service.
Provides database access for login related functions
public interface User x{
Loads a User
object for the record that
is returned
with the same username and password.
User
loadByUsernameAndPassword(String userName, String password);
}
The
test case
Before we begin development, we will develop our
test. Tests are structured by grouping methods that perform a test together in
a test case. A test case is a class that extends junit.framework.TestCase. So
in this case, we will begin by developing the test case for LoginService. To
start, in your test directory, create a new class named LoginServiceTest and
make it extend junit.framework.TestCase.
The lifecycle of a test execution consists of three
main methods:
public
void setUp()
setUp is executed before each of the test. It is
used to perform any setup required before the execution of your test. Your
implementation will override the default empty implementation in TestCase.
testSomething is the actual test method. You may
have many of these within a single test case. Each one will be executed by your
test runner and all errors will be reported at the end.
public
void tearDown()
tearDown is executed after each test method. It is
used to perform any cleanup required after your tests.
So to begin flushing out our test case, we'll start
with the setUp method. In this method, we'll instantiate an instance of the
service to be tested. We'll also create our first mock object, UserDAO. You can
see the source of our test below.