How Do I Test That? : Properties

December 28, 2004

Today I'm crafting an app that's configurable through properties. (No, not XML, just plain 'ol properties. Silly me.) I want to write a test that, when it passes, gives me confidence that system-level properties (e.g. -Dkey=value) override properties specified programmatically. How do I test that?

Well, I could fire up the test from the command line, once with a system property set and once without, but that's messy. And my tests are control freaks. They don't like relying on external input.

The solution I settled on is fairly pedestrian. In fact, I'm betting you already have an answer in mind. But since I've written a similar test more than once over the last couple years, I figured it might be worth posting.

Keep in mind, there's no guarantee as to the order in which the test methods will be run. Thus, each test method wants its own "sandbox". So, not only are my tests control freaks, they're also sharing-challenged. Here goes:

public class ConfigurationTest extends TestCase {

    private Properties originalProperties;
    
    public ConfigurationTest() {
        originalProperties = new Properties();
        originalProperties.putAll(System.getProperties());
    }
    
    public void tearDown() {
        System.setProperties(originalProperties);
    }

    public void testSetProperty() {
        String key = "key";
        String value = "setValue";
        
        Properties properties = new Properties();
        properties.setProperty(key, value);
        
        Configuration config = new Configuration(properties);
        assertEquals(value, config.getProperty(key));
    }

    public void testSystemPropertyOverridesSetProperty() {
        String key = "key";
        
        Properties properties = new Properties();
        properties.setProperty(key, "setValue");
        
        System.setProperty(key, "systemValue");
        
        Configuration config = new Configuration(properties);
        assertEquals("systemValue", config.getProperty(key));
    }
}

That's a lot of code for a little bit of testing, you say? Well, it does appear to be a disproportionate amount of code, but I generally err on the verbose side and then wait until enough pressure builds to force a refactoring. I just can't see a good refactoring from here that enhances readability. Perhaps you will. In the meantime, I can continue running these tests at no cost.

I enjoyed writing this test (yet again) because it reminded me of the value of testability hooks. In this case, I can bypass the command-line interface completely and set system-level properties once the system is running. I'm learning that if I write my code driven by tests, then odds are those hooks emerge naturally. That is, my tests uncover new methods based on need rather than speculation. And sometimes those methods turn out to be quite handy outside the context of a text.

Stumped trying to write a test? Let me know. We'll both learn!

Read more posts in the blog archive »