Integration Tests

What is an integration test

Sometimes there is not a clear distinction on what is an integration test and what is a unit test.

Basic rule of thumb is that if

  1. a test uses the database
  2. a test uses the network
  3. a test uses an external system (e.g. a queue or a mail server)
  4. a test reads/writes files or performs other I/O

…then it is an integration test and not a unit test. Below is brief comparison between the two. (more…)

Junit with Spring

Key Points

  • If test case class “extends TestCase”, it’s a JUnit 3.x test class. JUnit 4.x classes don’t need to inherit from anything, they use @Test annotations.
  • Ways to a make a test class Spring4 test:
    Option 1
    Extend AbstractTransactionalJUnit4SpringContextTests – Abstract base test class which integrates the Spring TestContext Framework with explicit ApplicationContext testing support in a JUnit environment.

    Option 2
    Add these annotations to your test class:

    @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class })

TestExecutionListeners are a way to externalize reusable code that instruments your tests.

As such, if you implement a TestExecutionListener you can reuse it across test class hierarchies and potentially across projects, depending on your needs.

On the flip side, a @BeforeClass method can naturally only be used within a single test class hierarchy.

Note, however, that JUnit also supports Rules: if you implement org.junit.rules.TestRule you can declare it as a @ClassRule to achieve the same thing… with the added benefit that a JUnit Rule can be reused just like a Spring TestExecutionListener.

So it really depends on your use case. If you only need to use the “before class” functionality in a single test class or a single test class hierarchy, then you’d be better off going the simple route of just implementing a @BeforeClass method. However, if you foresee that you will need the “before class” functionality in different test class hierarchies or across projects, you should consider implementing a custom TestExecutionListener or JUnit Rule.

The benefit of a Spring TestExecutionListener over a JUnit Rule is that a TestExecutionListener has access to the TestContext and therefore access to the Spring ApplicationContext which a JUnit Rule would not have access to. Furthermore, a TestExecutionListener can be automatically discovered and ordered.

  • Spring automatically wraps test methods in rollback-only transactions when test-case class is annotated with @Transactional. This has certain benefits: you won’t corrupt your database during the test and each test works on the same data, so you are not introducing inter-test dependencies.