Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test for errors in Spring Configuration?

In recent years I have been working on web applications written in Java using the Spring MVC framework. The projects have good test coverage with JUnit & Selenium. However on two occasions errors in the Spring Configuration have got through the testing process.

In one case a change was made to a parent bean in controllerContext.xml which also required a change to the two inheriting beans. But the required change was only made to one of the two inheriting beans. The error was only visible in a small, but critical, part of the Web application. Selenium UA tests were later extended to check this directly in the Web App. prior to deployment, but the damage had already been done as the error made it into the live environment.

In another case a property required to set the data format was not being injected properly via the applicationContext.xml. The only visible error was in the date format of a generated report downloaded from the web app. Difficult to test with Selenium.

One of the advantages of using Spring MVC is the ability to set the injected objects in your JUnit tests (i.e. a mock object), but this doesn't tell you what you are actually going to get injected when the Application is running in the live environment.

The answer may be integration testing, however setting up & running integration testing has proved to be difficult in the past ... but that's another question ...

So, I'd be really interested in learning how people have tried to catching possible errors introduced into Spring configuration files.

So my question is:

What is the best way to test for errors in the Spring Configuration?

like image 310
Richard Corfield Avatar asked Oct 14 '11 12:10

Richard Corfield


People also ask

What is @SpringBootTest used for?

Spring Boot provides a @SpringBootTest annotation, which can be used as an alternative to the standard spring-test @ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests through SpringApplication .

What is @ContextConfiguration in Spring Boot?

@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests.

How does @SpringBootTest work?

@SpringBootTest This annotation works by creating the ApplicationContext used in our tests through SpringApplication. It starts the embedded server, creates a web environment and then enables @Test methods to do integration testing. By default, @SpringBootTest does not start a server.


3 Answers

This test case will do the magic

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@ContextConfiguration(locations={"/server-application-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringConfigurationTest {

    @Test
    public void testSpringConfiguration() {
    }
}
like image 197
Bala Avatar answered Sep 28 '22 05:09

Bala


The type of bugs you describe will only be caught by tests when someone thinks/remembers to test these conditions:

In one case a change was made to a parent bean in controllerContext.xml which also required a change to the two inheriting beans. But the required change was only made to one of the two inheriting beans. The error was only visible in a small, but critical, part of the Web application. Selenium UA tests were later extended to check this directly in the Web App. prior to deployment, but the damage had already been done as the error made it into the live environment.

In another case a property required to set the data format was not being injected properly via the applicationContext.xml. The only visible error was in the date format of a generated report downloaded from the web app. Difficult to test with Selenium.

In both cases you have a developer who made a change without verifying that everywhere that change affects does not have errors. How can you catch this type of mistake in a JUnit-style test, without relying on the person making the change to explicitly add a test for the mistake they are making? In other words, you can only catch these types of bugs when you remember to test for them.

Personally I think the best approach for catching mistakes like this is more Selenium-like tests that actually invoke the application and assert the correct behavior.

But if your tests don't know the correct behavior to test, you can't catch mistakes like this - catching the mistakes requires you to first realize what mistakes need to be caught.

In other words - you can't test that the correct values are injected without the test knowing what the correct values are. These tests won't catch scenarios where what someone thinks the correct value is is actually incorrect.

like image 27
matt b Avatar answered Sep 28 '22 06:09

matt b


@ContextConfiguration(..) and @RunWith(SpringJUnit4ClassRunner.class) on your test class

That will load the entire context. You will need a dummy @Test method, so that the context is loaded.

like image 41
Bozho Avatar answered Sep 28 '22 05:09

Bozho