mainメソッドのテスト

テストしやすいことが良い設計」という話もあるので、被テストプログラムが自分のコントロール化にあるなら、リファクタリングしちゃうのがいいんじゃないかな。下のコードの様な感じ。元の話題とは少しずれるけど、自分ならこうするてことで。
あと、誰も指摘してない気がするんだけど、同じVM上で実行してしまったら、被テストプログラムで System.exit() をコールしちゃうとテストプログラムごと終了してしまってテストできない。そういう場合も java.lang.Process を使えばテストできなくはないけど、そこまでするなら割り切って別のスクリプト言語でテストしたほうがいい気もする。

import java.io.PrintStream;

public class Hello {
    PrintStream out;

    public Hello(PrintStream out) {
        this.out = out;
    }

    public void run() {
        out.println("Hello!");
        out.println("http://www.hyuki.com/");
    }

    public static void main(String[] args) {
        new Hello(System.out).run();
    }
}
import static org.junit.Assert.assertEquals;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class HelloTest {
    private ByteArrayOutputStream _baos;
    private PrintStream _out;

    @Before
    public void setUp() throws Exception {
        _baos = new ByteArrayOutputStream();
        _out = new PrintStream(_baos);
    }

    @After
    public void tearDown() throws Exception {
        _out.close();
    }

    @Test
    public void testHello() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream out = new PrintStream(baos);
        out.println("Hello");
        out.println("http://www.hyuki.com/");
        out.flush();
        
        new Hello(_out).run();
        _out.flush();
        
        assertEquals(baos.toString(), _baos.toString());
    }
}