Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit tests vs integration tests with Spring

I'm working on a Spring MVC project, and I have unit tests for all of the various components in the source tree.

For example, if I have a controller HomeController, which needs to have a LoginService injected into it, then in my unit test HomeControllerTest I simply instantiate the object as normal (outside of Spring) and inject the property:

protected void setUp() throws Exception {     super.setUp();     //...     controller = new HomeController();     controller.setLoginService( new SimpleLoginService() );     //... } 

This works great for testing each component as an isolated unit - except now that I have a few dozen classes in the project, after writing a class and writing a successful unit test for it, I keep forgetting to update my Spring MVC context file that does the actual wiring-up in the deployed application. I find out that I forgot to update the context file when I deploy the project to Tomcat and find a bunch of NullPointers from non-wired-up beans.

So, here are my questions:

  1. This is my first Spring project - is it normal to create unit tests for the individual beans, as I have done, and then create a second suite of tests (integration tests) to test that everything works as expected with the actual application context? Is there an established best practice for this?

  2. In addition, how do you separate the unit tests from the integration tests? I have all of the source code in src, the unit tests in test - should there be a 2nd test folder (such as test-integration) for integration test cases?

Since this is my first Spring project, I'm curious how others usually go about doing this sort of thing - and rather than re-invent the wheel I rather ask the rest of the community.

like image 432
matt b Avatar asked Nov 11 '08 18:11

matt b


People also ask

What is the difference between unit testing and integration testing in spring boot?

Unit tests run in isolation while integration tests bootstrap the Spring web context before execution starts. Running in isolation will sometimes require that you mock your dependencies based on the class you are testing.

Are integration tests better than unit tests?

While unit tests always take results from a single unit, such as a function call, integration tests may aggregate results from various parts and sources. In an integration test, there is no need to mock away parts of the application. You can replace external systems, but the application works in an integrated way.

What is the main difference between unit testing and integration testing?

Unit Testing is a kind of white box testing, whereas Integration Testing is a kind of black-box testing. For Unit Testing, accessibility of code is required, as it tests the written code, while for Integration Testing, access to code is not required, since it tests the interactions and interfaces between modules.

Does spring support integration testing?

The Spring Framework provides first-class support for integration testing in the spring-test module. The name of the actual JAR file might include the release version and might also be in the long org. springframework.


1 Answers

I can't speak to being a best practice, but here's what I've done in the past.

Unit tests:

  • Create unit tests for non-trivial beans (ie, most of your Spring related beans)
  • Use Mocks for injected services where practical (ie, most if not all the time).
  • Use a standard naming convention for these tests in the project test directory. Using Test or TestCase as a prefix or suffix to the classname seems to be widely practiced.

Integration Tests:

  • Create an AbstractIntegrationTestCase that sets up a Spring WebApplicationContext for use in intetgration test clases.
  • Use a naming convention for integration tests in the test directory. I've used IntTest or IntegrationTest as a prefix or suffix for these tests.

Set up three Ant test targets:

  1. test-all (or whatever you want to name it): Run Unit and Integration Tests
  2. test: Run Unit tests (just because test seems to be the most common usage for unit testing
  3. test-integration: run the integration tests.

As noted, you can use the naming conventions that make sense for your project.

As to separating unit from integration tests into a separate directory, I don't think it matters as long as the developers and their tools can find and execute them easily.

As an example, the last Java project I worked on with Spring used exactly what is described above, with integration tests and unit tests living in the same test directory. Grails projects, on the other hand, explicitly separate unit and integration test directories under a general test directory.

like image 163
Ken Gentle Avatar answered Sep 23 '22 08:09

Ken Gentle