Test Driven Dilemma


I hit a roadblock today and I’m not sure how to explain or get over it. The best I can do is offer an analogy. Suppose you have an interface that operated on input data and produced output data that you didn’t understand. Different implementations of the interface could produce different output. Without knowing the implementation details you want to test the interface and perform asserts on the output. The closest example I come up with that has nothing to do with my specific problem is a compiler interface.


import junit.framework.*;

import java.net.URL;
import java.io.ByteArrayOutputStream;

public class JavaSourceCompilerTest extends TestCase
{
    JavaSourceCompiler compiler;

    public void testCompile() throws Exception
    {
        URL resource = getClass().getResource("java/Test.java");
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        compiler.compileTo(output);
        assertTrue("Should not be empty", output.toByteArray().length > 0);
    }
}

interface JavaSourceCompiler{
    void compileTo(java.io.OutputStream sink);
}



In theory you want to test the interface. Also in theory you shoud be able to load any implementation in the test and get a green bar without recoding the test. Given these constraints what do you assert against? Think about it a minute because the test should work if compiler is instantiated with a JavaByteCode compiler implementation, a Groovy compiler, a JavaToDotNet compiler, or a JavaToCSource compiler. In other words your test can’t assert the specifics of the output. Now let’s say you want to enhance the interface to support source filtering. You want to be able to introduce a stoopid source filter that changes all occurences of the literal 42 with an expression that resolves to a random number like new Random().nextInt(). You want your test to assert that the filter was invoked prior to compilation. You can’t analyze the compiled output because from the interface perspective you don’t know what type of output is being produced. See? It becomes tough.

That’s where my problem lies. I’m not building compilers or anything fancy. I’m working with pricing logic. I have a strategy interface that exposes about a dozen different prices and blurs the algorithms used in the pricing. Testing the interface means that any price can be valid or I can’t assert the returned price against any specific value without the test being specific to any particular implementation. I also have the reqruiment of redirecting the strategy to use a different dataset as input to the pricing. There no easy way to assert that it’s using a different data set unless I impose knowledge of what the output prices should be with a given dataset. I suppose I could use mocks in some way. Holla back…