zoukankan      html  css  js  c++  java
  • Mock System.in和检查System.out

    做在单元测试的时候,会遇到测试数据依赖于用户输入的情况,类似于代码Scanner scanner = new Scanner(System.in);。下面提供一种方法,可以在测试过程中设置System.inSystem.out内容,很好地解决了模拟用户输入和检查输出的问题。

    public MockInOut(String input) {
        orig = System.out;
        irig = System.in;
     
        os = new ByteArrayOutputStream();
        try {
            System.setOut(new PrintStream(os, false, charset.name()));
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException(ex);
        }
     
        is = new ByteArrayInputStream(input.getBytes());
        System.setIn(is);
    }
    

    在这里设置了System.outSystem.in,因此我们可以在执行后完全获得输出,并且这次不需要手动输入,因为在的语句中Scanner scanner = new Scanner(System.in);,参数System.in是不会提示更改的,因此scanner.nextLine()将获得准备好的输入而无需等待。同样,输出将不会在控制台中打印,而是会累积到中ByteArrayOutputStream,随时可以访问。

    如果想恢复System.inSystem.out我们该怎么办?

    /**
     * 重置System.in、System.out
     */
    public void close() {
        os = null;
        is = null;
        System.setOut(orig);
        System.setIn(irig);
    }
    

    基本上,它会保存原始对象和内容,in并且out在需要恢复时,只需清楚stream并将原来的其放回原处,然后一切将照常进行。

    您可以在下面复制简单的示例代码以进行快速测试。

    import java.io.*;
    import java.util.*;
     
    class HelloWorld {
        
        public static void main(String[] args) throws IOException {
            PrintStream orig = System.out;
    
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            System.setOut(new PrintStream(os, false, "UTF-8"));
            // 这里不会打印
            for (int i = 0; i < 2; i++) {
                System.out.println("FunTester" + i);
            }
    
            System.setOut(orig);
            // 打印重置前输出内容
            output("收集到的输出内容:" + os.toString("UTF-8"));
    
            InputStream is = System.in;
            System.setIn(new ByteArrayInputStream("FunTester
    FunTester
    ".getBytes()));
            Scanner scanner = new Scanner(System.in);
            // 输出所有内容
            output(scanner.nextLine());
            output(scanner.nextLine());
            try {
                // 这里由于已经没有内容了,所以会报错
                System.out.println(scanner.nextLine());
            } catch (NoSuchElementException e) {
                e.printStackTrace();
            }
    
            System.setIn(is);
            scanner = new Scanner(System.in);
            // 这里会一直等待用户输入内容
            System.out.println("输入内容:" + scanner.nextLine());
        }
    

    实际上,注入和替换是一种用于分离单元测试依赖关系的常用方法,这对于仅关注代码非常有用。有很多高级和复杂的方法可以执行此操作,但是在这里,我们只想解释一种简单的方法,即mock以便可以专注于代码。


    • 郑重声明:“FunTester”首发,欢迎关注交流,禁止第三方转载。

    技术类文章精选

    无代码文章精选

  • 相关阅读:
    拓展欧几里得
    使用BIOS进行键盘输入和磁盘读写
    直接定址表
    指令系统总结
    端口
    内中断
    标志寄存器
    call 和 ret 指令
    编写包含多个功能子程序的中断例程
    字符串的输入
  • 原文地址:https://www.cnblogs.com/FunTester/p/12792025.html
Copyright © 2011-2022 走看看