Announcement Announcement Module
No announcement yet.
Doing Integration Testing on a multi-layer application Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Doing Integration Testing on a multi-layer application

    The application I'm working on is a pretty straightforward struts/spring web application: there is a database layer, a services (business classes) layer and a struts layer. All of these layers are seperate projects in my development group, each has its own application context xml file to wire them together and each compiles into a JAR file for usage in the main application. The thought being that the main application will get a JAR file and spring config file for each layer.

    My problem is that I want to test each layer as a unit with as little coupling to the layers other than the one just below (for instance the WEB layer should know nothing about the DB layer and only work with the Services layer, etc.).

    But, Spring when it loads the contexts doesn't care about these layers and needs to create (and be aware) of all the beans in total so even if the WEB layer XML file references only beans in the SERVICES XML file, the fact that the SERVICES beans reference the DB beans makes this a big issue. I essentally have to load all the lower level beans to do any testing on any layer.

    What I would like is to be able to simply test that the beans in the layer I'm testing can be created and not worry about the lower levels. In a sense I want to stub out the dependancies or mock them in some way. I've tried a number of ways to do that but have had little luck.

    My question is this. Since I'm sure others have build an app this way, how do they test in this situation? And I guess I'm also curious if my method seems sound.

  • #2
    Doing Integration Testing on a multi-layer application...I want to test each layer as a unit with as little coupling to the layers
    If you're doing integration testing, combining all the layers should be a valid and significant test.

    If you want to test the projects in isolation, try sticking to pure Unit tests, or very small integration tests, where the interfaces to the lower levels are mocked out. Take a look at EasyMock and JMock to assist with this. You might find some useful classes in Spring's spring-mock JAR.


    • #3
      Using AbstractDependencyInjectionSpringContextTests

      If you're using AbstractDependencyInjectionSpringContextTests, you can override its getConfigLocations() method so that it returns :
      • the real config file(s) for the tier(s) you want to test
      • fake config files for the tiers you want to mock or replace with test versions (e.g. a test database that could even be an in-memory one)
      The other approach I've used is to load the lower-tier stubs/mocks into a StaticApplicationContext, then use that as the parent context for a FileSystemXmlApplicationContext that uses the real config files for the layer you're testing. Here's what I mean:

      // Create a static application context to contain the mocks
      StaticApplicationContext staticApplicationContext = new StaticApplicationContext();
      // Create the mocks and register them with this application context
      Foo mockFoo = createNiceMock(Foo.class);
      staticApplicationContext.getBeanFactory().registerSingleton("foo", mockFoo);
      // Make a new context based on the one containing the mocks, using the wiring information contained in the live XML files for the tier under test
      String[] configFileNames = ... ;
      ApplicationContext applicationContext = new FileSystemXmlApplicationContext(configFileNames, staticApplicationContext);
      // Get beans from the "applicationContext" and test them as desired


      • #4
        Ok.. so in either case you guys are saying that the best thing would be to actually mock all the lower level dependancies in code. I was hoping to not have to do that but it seems like I will have to. I use Jmock all over the place so I certainly can handle it.

        Andrews, your idea is a very good one. I can can create the static context in a parent test fixture and be all set to do these tests in all the children.

        I guess these aren't full integration tests as they are strictly defined, but that is based on the scope of them. In a particular layer, there are integration issues with the layer below it so that is why I was saying this was an integration test issue..