Unit Test Summary
Unit tests are meant to be created quickly and run quickly, providing you with a safety net
for eventual refactorings and helping to design a simpler system. Writing tests for the obvious
situations isn’t enough; make sure to consider the edge cases of the code and to test all logic
branches and exceptional conditions. A code coverage utility can help in tracking which code
is actually tested.
It’s important to view the list of unit test tenets not as hard and fast rules, but as guide-
lines to help you write the most effective unit tests possible. The important elements of unit
tests, running fast and independently, should permeate all the tests you create. Remember
that unit tests are written by you, for you. Keep them easy to create and easy to run, and they
will continue to be useful for you.
We recommend that unit tests should be created as early as possible, ideally concurrently
with the module’s creation.
Using mock objects will isolate the class under test to ensure that external variables are
removed from the test. Mock objects also allow a unit test to run without the presence of the
dependency so that the test can run quickly and without risk of affecting the outside world.
Mocks are also a very good way, and sometimes the only way, to test how your code will react
when the dependency behaves under edge cases or in unexpected ways.
Spring provides stubs for easy testing with J2EE APIs such as the Servlet API. You should
use these classes, such as MockHttpServletRequestand MockHttpServletResponse, when writ-
ing tests for Controllers or other web components. These stubs are very easy to use, and make
writing tests for Controllers as easy as testing any other Java class. As with writing all other
unit tests, when testing Controllers be sure to adhere to the principles of “run fast” and “zero
external configuration.”
Some test situations and scenarios, however, simply do not fit into the criteria for a unit
test. If you find you need to write tests that test the interaction between components, you are
writing what is called an integration test. We will discuss integration tests throughout the rest
of the chapter. Let’s define them now.
Integration Tests
We have painted a picture of unit tests as fast, small, lightweight tests that are quick to write
and run. Unit tests are designed to test the smallest elements of your system, isolating each
element and module from the rest of the system. These types of tests not only help ensure cor-
rectness for your system, but also help direct the design of your code—that is, your code needs
to become modular if unit tests can be written effectively in the first place.
Unit tests are excellent for the components of the system that comprise the business
logic. However, there is a lot of code in the system that isn’t necessarily business logic, usually
in the form of database interaction code (the DAOs). Testing these components can quickly
break the rules that we try to follow for unit tests. For example, a unit test shouldn’t interact
with external systems such as the database, but how are you supposed to test your DAO
classes? Also, a unit test should test a component in isolation, but how are you supposed to
test that your entire system is wired together properly inside the ApplicationContext?
Enter integration tests: tests written with the same testing framework as your unit tests,
but created specifically to test the interaction between the components of your system. Inte-
gration tests look a lot like unit tests, but they differ on their scope and intention. We’re also
302 CHAPTER 10 ■TESTING SPRING MVC APPLICATIONS