【问题标题】:Test InputStream with Junit使用 Junit 测试 InputStream
【发布时间】:2018-01-19 18:53:36
【问题描述】:

我正在尝试在我的类“UserInput”中测试一个函数“DataFeatures”。

我在测试中给出什么参数并不重要,它总是通过。

字段和构造函数

public @Getter class UserInput {
    FileType type;
    FileOperation operation;
    SynchronizationMethod method;
    String path;
    private static InputReader in = new InputReader();

    public UserInput() {
        // Dont need to do anything
    }

要测试的功能

    void getDataFeatures() {
    System.out.println("For encryption press 1");
    System.out.println("For decryption press 0");
    operation = FileOperation.fromInt(in.nextInt());

    System.out.println("For a file choose 1");
    System.out.println("For an entire directory choose 0");
    type = FileType.fromInt(in.nextInt());

    if (type == FileType.DIR) {
        System.out.println("For sync press 1");
        System.out.println("For async press 0");
        method = SynchronizationMethod.fromInt(in.nextInt());
    }
}

我的测试

public class UserInputTest {

UserInput UI;
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
private final PrintStream oldStdOut = System.out;
private final PrintStream oldStdErr = System.err;
private final InputStream oldStdIn = System.in;

@Before
public void initlize(){
    System.setOut(new PrintStream(outContent));
    System.setErr(new PrintStream(errContent));
    UI = new UserInput();
}

@Test
public void getDataFeaturesTest() {
    String data = "0" + "\n0" + "\n0";
    System.setIn(new ByteArrayInputStream(data.getBytes()));
    UI.getDataFeatures();
    System.out.println(UI.getOperation());
    assertThat(UI.getOperation(), is(equalTo(FileOperation.decryption)));
    assertThat(UI.getType(), is(equalTo(FileType.FILE)));
    assertThat(UI.getMethod(), is(equalTo(SynchronizationMethod.SYNC)));


}

@After
public void cleanUpStreams() {
    System.setOut(oldStdOut);
    System.setErr(oldStdErr);
    System.setIn(oldStdIn);
}

}

注1:FileOperation、FileType和SynchronizationMethod都是取1或0的枚举。

同步方法示例:

public enum SynchronizationMethod {
SYNC(1), ASYNC(0);

private int method;

private SynchronizationMethod(int meth) {
    this.method = meth;
}

public static SynchronizationMethod fromInt(int meth) {
    for (SynchronizationMethod SM : SynchronizationMethod.values()) {
        if (SM.method == meth) {
            return SM;
        }
    }
    throw new IllegalArgumentException("No constant with method " + meth + " found");
}

public String toString(){
    if (method == 1){
        return "Sync";
    }
    else if(method == 0){
        return "ASync";
    }
    else{
        throw new IllegalArgumentException("No constant with method " + method + " found in toString");
    }
}

}

解决方案

问题出在构造函数中的 InputReader 类中。

    public InputReader() {
    reader = new BufferedReader(new InputStreamReader(System.in));
    tokenizer = null;
}

此函数中的 reader 和 Junit 函数中的 Input Stream 如 cmets 中所建议的那样断开

【问题讨论】:

  • 好的,我改了
  • 不相关:我建议将您的枚举基于 int 数字。枚举已经有办法从字符串中构建常量。你在这里重新发明轮子。您可以决定将枚举值表示为小写字符串,并且从“同步”创建 SYNC 的代码(反之亦然)应该大大更短!说真的:无论如何,当您要求用户输入时不要使用数字。为什么要让用户记住 0 是异步的。让我让他说“异步”吧!
  • 我提出了一个答案,但重点是:您确实没有提供minimal reproducible example。我们不可能重现您的问题 - 因为您只有部分代码会产生问题。如果我的回答有帮助,那很好。如果没有:请阅读该链接minimal reproducible example 并提供符合这些要求的代码!
  • 例如,通过对 Java 枚举所具有的现有方法进行一些研究。更重要的是:用户不会犯错误,或者他可以省去输入几个字符?

标签: java junit inputstream


【解决方案1】:

猜测 - 你的 UserInput 类说:

private static InputReader in = new InputReader();

而你的测试用例说:

String data = "0" + "\n0" + "\n0";
System.setIn(new ByteArrayInputStream(data.getBytes()));

换句话说:有可能断开。根据InputReader 背后的实现,您可能只是从错误的来源读取。

【讨论】:

    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多