用junit测试控制台输入

今天我写了一个键盘类的输入功能,这个类长这样,它继承自一个键盘接口。

public interface KeyBoard {
    String input();
}
public class KeyBoardImpl implements KeyBoard {
    @Override
    public String input() {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        return input;
    }
}

为了测试这个类的输入功能,我写了这样一个测试用例,用的是junit

public class KeyBoardImplTest {
    KeyBoard keyBoard = new KeyBoardImpl();

    @Test
    public void test() {
        String input = keyBoard.input();
        System.out.println(input);
    }
}

但是我在运行该测试用例后,发现无法在控制台输入任何内容,程序停在那里不动了。

我尝试了一下在main函数里面写个用例,发现能够输入。

public class KeyBoardImpl implements KeyBoard {
    @Override
    public String input() {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        return input;
    }

    public static void main(String[] args) {
        KeyBoard keyBoard = new KeyBoardImpl();
        String input = keyBoard.input();
        System.out.printf(input);
    }
}

image.png

这是为啥呢,经过网上搜索,我找到了解决方案,并且大致了解了原因: junit是用例自动化单元测试的,那么控制台输入这个人工操作就应该不会支持,解决方案如下

https://stackoverflow.com/questions/1647907/junit-how-to-simulate-system-in-testing
上面链接中得票最多的一条的基本做法是:把输入流redirect到字符串输入,把要输入的字符串写入,运行测试案例,再把输入流重新设置为控制台输入,我按照这种方法修改了测试用例:

public class KeyBoardImplTest {
    KeyBoard keyBoard = new KeyBoardImpl();

    @Test
    public void testInput() throws Exception {
        String data = "Hello, World!\r\n";
        String input;
        InputStream stdin = System.in;
        try {
            System.setIn(new ByteArrayInputStream(data.getBytes()));
            input = keyBoard.input();
        } finally {
            System.setIn(stdin);
        }
        System.out.println("input is----" + input);
    }
}

运行该测试用例,得到了希望的结果:



作者:ThomasYoungK
链接:https://www.jianshu.com/p/86fe4314ec53
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

猜你喜欢

转载自blog.csdn.net/pange1991/article/details/81135151