Expert Spring MVC and Web Flow

(Dana P.) #1

allowed to bend the rules mentioned above, while keeping with the main themes of quickness,
repeatability, and isolation.


Bend, Don’t Break


When you create an integration test, you are openly acknowledging that you are testing the
interaction between two components of the system. Many times, this might mean you are
even writing tests that interact with the database. As you create these tests, keep in mind the
tenets that make unit tests so successful.



  • Leave external state untouched: Even though an integration test might interact with the
    database, when the test is finished it must leave that database in a clean state. The data-
    base, or any external resource, must be left in the same state it was in before the test
    ran. For example, this means you must roll back the database transaction after each
    test run. It’s a safe and simple way to ensure the database is not changed.

  • Isolated external resources: We argued that for unit tests, there should be no external
    resources involved. For an integration test, though, testing the interaction with the
    external resource is the whole point. However, the test should exercise only one exter-
    nal resource at a time to minimize the areas affected and to keep the test run times as
    low as possible.

  • Run fast: Still as important for integration tests as it is for unit tests, all of your tests
    should run extremely fast. This is related to keeping each test dependent on only
    one external resource, as well as smart resource management. For instance, if your
    integration test requires a Spring ApplicationContext, caching the context instance
    across test runs can greatly speed up the test runs. Of course, if your test alters the
    ApplicationContext, you will want to recreate the context for every test run.

  • Test smallest unit of code: Even though integration tests are written testing two compo-
    nents of the system, each individual test must still exercise a single method of the class
    under test. Keeping the amount of code under test to a minimum is extremely helpful
    when a bug is inevitably found, as it minimizes the amount of code you have to search
    through.


As you can see, the basic guidelines for integration tests mesh well with unit tests.
However, with integration tests, we are explicitly testing the interaction of two or more com-
ponents in the system. With Spring applications, this type of testing becomes quite important
because of the amount of configuration and the extent it reaches into the system.
If we take a step back and look at the range of testing types, we might consider the com-
piler itself to be a type of test. It is ensuring that access modifiers are obeyed, that the correct
number of parameters is used, and that you are returning the correct type of object from a
method. These are fundamental checks we must perform before the system is ever run, and
the compiler is performing these syntactical tests for use before compilation. Moving up the
scale in terms of scope, we then encounter unit tests, mentioned earlier in this chapter. Here
we are testing small units of code, such as methods. So far, though, we’ve only essentially
tested Java code. External system-level configurations have yet to be tested, and yet they are
as important as any Java code we write.


CHAPTER 10 ■TESTING SPRING MVC APPLICATIONS 303
Free download pdf