スキャナーを使用してsystem.inから読み取り、system.outに出力する単純なメインメソッドのコマンドラインクラスをJUnitでテストするにはどうすればよいですか。
import java.util.Scanner;
public class SimpleMainCmdApplication {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.next());
}
}
これは、参加者がSystem.inから読み取り(スキャナーを使用)、System.outに回答を出力するmainメソッドを使用して* .javaファイルをアップロードする必要があるコースデータ構造とアルゴリズムコースを実行している非常に特殊なユースケースです。コードをアップロードすると、Webサイトはアプリケーションを構築して実行し、アルゴリズムのパフォーマンスをテストおよび測定します。
これをシミュレートする方法が欲しかったので、各割り当てにTDDアプローチを採用する一環として、JUnitを使用して簡単な統合テストを作成できます。他のスタックオーバーフロースレッドには役立つポインタがいくつかありましたが、完全な要件を満たすものはありませんでした。
これを解決するために、コマンドライン入力とリフレクションで呼び出すメインメソッドクラスの名前を渡すことができるプライベートメソッドを作成しました。次に、標準のハムクレストマッカーを出力に適用できます。
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
public class MainCmdTest {
private ByteArrayOutputStream byteArrayOutputStream;
private PrintStream console;
@Before
public void setup() {
byteArrayOutputStream = new ByteArrayOutputStream();
console = System.out;
}
@Test
public void shouldPrintTest() throws Exception {
runTest("test", "SimpleMainCmdApplication");
assertThat(byteArrayOutputStream.toString(), is("test\n"));
}
private void runTest(final String data, final String className) throws Exception {
final InputStream input = new ByteArrayInputStream(data.getBytes("UTF-8"));
final InputStream old = System.in;
try {
System.setOut(new PrintStream(byteArrayOutputStream));
System.setIn(input);
final Class<?> cls = Class.forName(className);
final Method meth = cls.getDeclaredMethod("main", String[].class);
final String[] params = new String[]{};
meth.invoke(null, (Object) params);
} finally {
System.setOut(console);
System.setIn(old);
}
}
}
実際の実装では、コードの実行にかかる時間も測定し、テスト対象のしきい値制限を設定できます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加