【问题标题】:How to test a simple command line application in Java using JUnit [closed]如何使用 JUnit 在 Java 中测试一个简单的命令行应用程序 [关闭]
【发布时间】:2017-09-12 10:25:50
【问题描述】:

我如何 JUnit 测试我的简单 main 方法命令行类,它使用 Scanner 从 system.in 读取并打印到 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());
    }
}

这是一个非常具体的用例,我正在做一门课程数据结构和算法课程,它要求参与者上传一个 *.java 文件,该文件的主要方法是从 System.in(使用扫描仪)读取并将答案输出到 System 。出去。当您上传代码时,网站会构建和运行应用程序,并测试和衡量算法的性能。

我想要一种模拟这种情况的方法,这样我就可以使用 JUnit 编写简单的集成测试,作为对每个分配采用 TDD 方法的一部分。在其他堆栈溢出线程上有一些有用的指针有所帮助,但没有一个能满足全部要求。

【问题讨论】:

    标签: java algorithm testing junit command-line-tool


    【解决方案1】:

    为了解决这个问题,我创建了一个私有方法,我可以从中传递命令行输入和我想通过反射调用的主方法类的名称。然后我可以将标准 hamcrest macthers 应用于输出。

    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);
            }
        }
    }
    

    在实际实现中,我还测量了执行代码所需的时间,并能够设置阈值限制以进行测试。

    【讨论】:

    • 它在与您的 JUnit 相同的 JVM 中工作。我想说,这不是一个干净的测试。
    猜你喜欢
    • 2021-12-23
    • 2014-06-28
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多