algorithm - How to test a simple command line application in Java using JUnit -
how can junit test simple main method command line class reads system.in using scanner , prints system.out.
import java.util.scanner; public class simplemaincmdapplication { public static void main(string args[]) { scanner scanner = new scanner(system.in); system.out.println(scanner.next()); } }
this quite specific use case doing course data structures , algorithms course requires participants upload *.java file main method reads system.in (using scanner) , outputs answers system.out. when upload code website builds , runs application , tests , measures performance of algorithm.
i wanted way simulate can write simple integration tests using junit part of taking tdd approach each assignment. there useful pointers on other stack overflow threads helped, nothing met full requirements.
to solve created private method can pass command line inputs , name of main method class want invoke reflection. can apply standard hamcrest macthers output.
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); } { system.setout(console); system.setin(old); } } }
in actual implementation measure time takes execute code , able set threshold limits test against.
Comments
Post a Comment