テストとファサードの関係
テスト駆動型のアプローチでは、ファサードを作る場合が多いと思われます。テスト駆動開発(TDD)では、システム設計の際に、パブリックインターフェースを通じてクラスの動作を実証するテストを記述します。単体テストのコンセプトやポリシーを簡潔に表現したいと考える開発者であれば、ベースになるAPIとの対応付けを行うために、何らかの変換(つまりファサード)が必要だと気付くでしょう。
リスト2に、Commandクラスに対するテストを示します。このCommandTestクラスの興味深いところは、自分自身をテスト対象のコマンドラインアプリケーションとして使用する点です。この自己シャント(self-shunt)の仕組みにより、外部のアプリケーションやOSとの依存関係をなくしています。
import static org.junit.Assert.*;
import org.junit.*;
public class CommandTest {
enum TestName {
testSingleLine("a short line of text"),
testMultipleLines("line 1\\nline2\\n"),
testLotsOfLines("") {
String outputText() {
final int lots = 1024;
StringBuilder lotsBuffer = new StringBuilder();
for (int i = 0; i < lots; i++)
lotsBuffer.append("" + i);
return lotsBuffer.toString();
}
};
private String outputText;
TestName(String outputText) {
this.outputText = outputText;
}
String outputText() {
return outputText;
}
}
private Command command;
public static void main(String[] args) {
TestName testName = TestName.valueOf(args[0]);
System.out.println(output(testName));
System.err.println(syserrOutput(testName));
}
private static String syserrOutput(TestName testName) {
return testName.outputText.toUpperCase();
}
private static String output(TestName testName) {
return testName.outputText();
}
@Test
public void successfullyExecutesSingleLine()
throws Exception {
executeCommand(TestName.testSingleLine);
verifyOutput(TestName.testSingleLine);
}
@Test
public void successfullyExecutesMultipleLines()
throws Exception {
executeCommand(TestName.testMultipleLines);
verifyOutput(TestName.testMultipleLines);
}
@Test
public void successfullyExecutesLotsOfLines()
throws Exception {
executeCommand(TestName.testLotsOfLines);
verifyOutput(TestName.testLotsOfLines);
}
private void executeCommand(TestName testName)
throws Exception {
command = new Command(commandString(testName));
command.execute();
}
private void verifyOutput(TestName testName)
throws Exception {
assertEquals(output(testName), command.getOutput());
assertEquals(syserrOutput(testName),
command.getErrorOutput());
}
private String[] commandString(TestName testName) {
return new String[] { "java", "-classpath",
"\"" + System.getProperty("java.class.path")
+ "\"", "CommandTest",
testName.toString() };
}
}

