Recently while testing a spring-based app, we required the ability to change the test case values frequently. We had the tests, mocking framework and test suites but we needed to have the ability to choose what values get passed to the test cases for the next run we trigger, especially for business use cases.

The usual habit was to have the JUnit test classes declare tests and assert, as anyone would do, but how would that change the inputs/expected values for a single run?

Enter –  Externalizing the test case configuration!

One of the highlights of spring is DI: Dependency Inject a.k.a. Inversion of Control. That’s a ‘techy’ term for a simple (yet powerful) way to design classes, which means that the class allows its dependencies (Has-a) ‘injected’ in it at the time of instantiation. Well, we won’t be discussing what DI means here (I have made a promise that I will keep this and next few posts short!), there is plenty of documentation available online. But this just sets the context.

Lets assume that we want to test our class “Superb”, and our test class is “SuperbTest”

Let’s begin then. This is how our usual testContext.xml file would look like:

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
        <context:annotation-config />
        <context:component-scan base-package="com.demoapps" />
        <context:property-placeholder location="classpath:TestCaseProps.properties" />
beans>

Nothing special here or in the part that we are reading a TestConfigProps.properties file, but what that file has is somewhat interesting. And what does the properties file look like?

#Superb
Superb.input.users.user1=Nikhil
Superb.output.users.user1=Smart
Superb.input.users.user2=Nikhil2
Superb.output.users.user2=Wow
 
Superb.currentSetup.users=user1

We have to agree to a simple naming convention for the property names and we have an input/output matching pattern. The pattern dictates that we retain the category (“users”) and the id (“1”/”2”) across the input and output groups and we can match them to test output.

The last part of the puzzle:

package com.demoapps;
 
// imports
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:testContext.xml"}) // and others, if you have.
public class SuperbTest {
        @Value("$  {Superb.input.users.$  {Superb.currentSetup.users}}")
        String testInput;
 
        @Value("$  {Superb.output.users.$  {Superb.currentSetup.users}}")
        String testOutput;
 
        @Test
        public void myTest() {
                assertEquals(SomeClass.someAwesomeMethod(testInput), testOutput);
        }
}

That was simple.

This method lets us externalize simple input and output values for tests. Although this lets us externalize output values, we now realize that we use it more to externalize only the inputs. Especially in cases where the inputs need to change from time to time. Also, it works best with Strings – other types, not so much.

A drawback of this method is that it works only with simple types. You cannot externalize large objects this way. But maybe it can be enhanced to accept paths to serialized objects instead.

By |November 11th, 2014|Technology, Testing|0 Comments

About the Author:

 Externalizing Test Case Configuration While Unit Testing Spring Application
Working as a tech lead at e-Zest, Nikhil is engaged in technologies such as Node.js and javascript TABit team. Having completed BE in Biotechnology, he has expertise in Java and JavaScript. Nikhil has total 6 years of experience. In his free time he loves reading and hiking.

This entry passed through the Full-Text RSS service – if this is your content and you’re reading it on someone else’s site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.

e-Zest | India | USA | UK | Germany | Europe