【问题标题】:How can I unit test user input in java如何在java中对用户输入进行单元测试
【发布时间】:2013-04-17 17:45:18
【问题描述】:

我正在尝试了解如何测试用户的输入(请注意,我不是在尝试进行模拟测试,而是对实际用户输入的测试)

目前,正如您在我的程序中看到的那样,我已经对我的测试用例的值进行了硬编码,并且它通过了所有测试,但是我怎样才能获得用户的输入并对其进行测试。

当我在测试类中创建 MyClass1 的实例时,有没有一种方法可以在我的构造函数中调用 System. 并传递它?

如果可能的话,请给我一些示例代码,以便我更好地理解。

如果我有这样的界面

public interface IMyClass{
   public int getvalue1();
   public int getvalue2();
   public int getvalue3();
}

然后是接口实现

public class MyClass1 implements MyClass{

private int _value1 = 0;
private int _value2 = 0;
private int _value3 = 0;



public MyClass1(int number1, int number2, int number3)
{

   _value1 = number1;
    _value2 = number2;
    _value3 = number3;
}

public void setLength1(int value1)
{
    _value1 = value1;
}

public void setLength2(int length2)
{
    _value2 = value2;
}

public void setLength3(int length3)
{
    _value3 = value3;
}

public int getValue1()
{
    return _value1;
}

public int getValue2()
{
    return _value2;
}

public int getValue3()
{
    return _value3;
}
}

最后是这样的测试类:

public class ClasTest extends TestCase {

public void testNumbers()
{
   MyClass1 numbers= new MyClass1(1,2,3);
   assertThat(numbers.getValue1(),is(not(numbers.getValue2())));

}
}

谢谢,感谢您的帮助。

【问题讨论】:

  • MVC,MVP?有什么设计模式吗?
  • 从测试的角度来看,您在测试中所做的就足够了。唯一可能的方法是随机生成输入并根据该随机输入进行测试。
  • 为什么不在您的测试中使用硬编码值?您只需要考虑特殊情况(如 Integer.MAX_VALUE、0 等边界)还混合了一些正数和负数,也许这就足够了。这个基本案例应该涵盖所有其他案例。
  • 是的,但我该如何测试呢?
  • 究竟测试什么?您没有显示任何涉及用户输入的测试代码。以任何方式(System.in、Scanner 等)从控制台读取单元测试本身并不是单元测试的工作方式——单元测试应该是自动化的,而不是依赖于人工交互。

标签: java unit-testing


【解决方案1】:

使用System.setIn(new InputSteam());,然后写入传入System.in的输入流

见:JUnit: How to simulate System.in testing?

单输入

String data = "Users Input";
System.setIn(new ByteArrayInputStream(data.getBytes()));

Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextLine());

结果

Users Input

多个输入

String data = "Users Input" +
        "\nA second line of user input.";
System.setIn(new ByteArrayInputStream(data.getBytes()));

Scanner scanner = new Scanner(System.in);
System.out.println("Line 1: " + scanner.nextLine());
System.out.println("Line 2: " + scanner.nextLine());

结果

Line 1: Users Input
Line 2: A second line of user input.

【讨论】:

  • 能否分享一个使用 System.setIn 的示例?谢谢
  • 这仅适用于一个输入。如果你想要多个输入(即程序提示输入几次,它不起作用)
  • @Imray 这确实有效,请参阅更新的示例。您只需将所有输入放入输入数据中。
【解决方案2】:

如果在 unix 上

java MyProgram < sampleinput.txt

【讨论】:

  • 我不在 unix 上,也不太了解 unix。而且我没有从 .txt 文件中读取。我正在从控制台阅读。不过谢谢
  • @user1462617 这会将标准输入重定向到从示例文本文件而不是从控制台读取。
  • 是的,我明白这一点。这就是为什么我说我不是从文件读取,而是从控制台读取
  • @user1462617 那么每次运行测试时,您都需要聘请某人将输入输入到控制台中。如果不使用带有测试输入的文件,我不知道您希望如何进行测试。
【解决方案3】:

用户扫描器类

public void testNumbers()
{

    Scanner scan = new Scanner(System.in);
    System.out.println("value1");
    int value1 = scan.nextInt();

    System.out.println("value2");
    int  value2 = scan.nextInt();

    System.out.println("value3");
    int value3 = scan.nextInt();

   MyClass1 numbers= new MyClass1(value1, value2, value3);
   assertThat(numbers.getValue1(),is(not(numbers.getValue2())));

}

【讨论】:

  • 我知道扫描仪类,但我该如何测试它。在我的测试类中,我创建了类实例: MyClass1 numbers = new numbers(1,2,3) //这是默认构造函数。我不能做类似数字(System.nextInt(),...)之类的事情。
  • 编辑了答案。获取用户输入并将它们保存在变量中,然后将其传递给构造函数
  • 使用 scan.nextInt();如果你想来自用户的 int 输入
  • 在我看来,在单元测试中使用 System.in 没有多大意义。
  • 但他有接受用户输入的要求。这就是您在 Java 中获取用户输入的方式。理想情况下,要么对数据进行硬编码,要么使用某种模拟框架。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2020-02-29
  • 1970-01-01
  • 2012-01-08
相关资源
最近更新 更多