Code to redirect console IO to strings This code allows calling a method while redirecting the IO to strings.  This is useful for unit testing where you have to direct something to the console or examine output that comes from it.  I assume these have been written a lot, but I couldn't find examples.

I'd like advice on how to make them generally useful and whether the style seems decent.  There are two methods-- one sends a string to System.in while leaving the output alone, the other redirects both input and output, with the option that if the input string passed is null, it leaves the input alone.  This covers all three cases.

Invocations look like this:

enterInput(inputString, callingClassString, methodString, typeStrings[], argsForCall ...);
captureIO(inputString, callingClassString, methodString, typeStrings[], argsForCall ...);


Code:

/**
 * Invoke the specified method using the specified string as console input.
 * Note that the calling class and types must be fully qualified.
 * 
 * @param inputString               Console input to be fed to the method
 * @param callingClassString        Class of the method to invoke
 * @param method                    Name of the method to invoke
 * @param typeStrings               Types the method takes (to distinguish it)
 * @param args                      Arguments to pass to the method
 * @return                          The console output captured
 */
public static void enterInput(String inputString,
        String callingClassString, String method, String[] typeStrings,
        Object... args) {
    try {
        Class&lt;?&gt;[] typeClasses = new Class&lt;?&gt;[typeStrings.length];
        for (int i = 0; i &lt; typeStrings.length; i++) {
            typeClasses[i] = Class.forName(typeStrings[i]);
        }

        Method m = Class.forName(callingClassString).getMethod(method, typeClasses);
        InputStream origIn = System.in;
        System.setIn(new ByteArrayInputStream(inputString.getBytes()));
        m.invoke(null, args);
        System.setIn(origIn);
    } catch (Exception e) {
        throw new Error(e);
    }
}

/**
 * Invoke the specified method and return its console output as a string.
 * If inputString is not null, it is used as console input.
 * Note that the calling class and types must be fully qualified.
 * 
 * @param inputString               Console input to be fed to the method.
 *                                  If null, leaves this input stream alone
 * @param callingClassString        Class of the method to invoke
 * @param method                    Name of the method to invoke
 * @param typeStrings               Types the method takes (to distinguish it)
 * @param args                      Arguments to pass to the method
 * @return                          The console output captured
 */
public static String captureIO(String inputString, String callingClassString, String method, 
        String[] typeStrings, Object ... args) {
    String output = null;

    try {
        Class&lt;?&gt;[] typeClasses = new Class&lt;?&gt;[typeStrings.length];
        for (int i=0; i&lt;typeStrings.length; i++) {
            typeClasses[i] = Class.forName(typeStrings[i]);
        }

        Method m = Class.forName(callingClassString).getMethod(method, typeClasses);
        InputStream origIn = System.in;
        PrintStream origOut = System.out;

        if (inputString != null)
            System.setIn(new ByteArrayInputStream(inputString.getBytes()));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        System.setOut(new PrintStream(baos));
        m.invoke(null, args);
        output = baos.toString();

        System.setOut(origOut);
        if (inputString != null)
            System.setIn(origIn);
    } catch (Exception e) {
        throw new Error(e);
    }
    return output;
}
This (and reflection in general) completely breaks refactoring, static code analysis and many more things and should therefore be avoided. (Imagine what happens if you find out a better naming for a function or you change the arguments.)

If you really need this behavior, you could use (I assume jUnit 4+) hooks before and after class/test case:

@BeforeClass
public static void setUpBeforeClass() throws Exception {
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
}

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}


and do whatever is necessary.
Besides this, as already written, I would suggest to modify your methods, too. It could be a better approach to separate the view (prints) from model/controller (functions doing something).