Java 如何使用junit/mockito为CLI编写测试用例

Java 如何使用junit/mockito为CLI编写测试用例,java,junit,mockito,powermock,powermockito,Java,Junit,Mockito,Powermock,Powermockito,我需要使用junit和模拟框架(如mockito)为下面的代码编写测试用例,这是一个命令行实用程序 public class Line { private final Header header; int readLines() { Console con = System.console(); String message; ArrayList<MEnum> mList = new ArrayList<>();

我需要使用junit和模拟框架(如mockito)为下面的代码编写测试用例,这是一个命令行实用程序

public class Line {
  private final Header header;      

  int readLines()
  { 
    Console con = System.console();
    String message;
    ArrayList<MEnum> mList = new ArrayList<>();
    boolean exit = false;

    while (!exit) {
    message = "";

    System.out.println("Please enter Key");

    mList.clear();

    return 0;
  }
}
公共类行{
专用最终标题;
int readLines()
{ 
Console con=System.Console();
字符串消息;
ArrayList mList=新的ArrayList();
布尔退出=假;
当(!退出){
message=“”;
System.out.println(“请输入键”);
mList.clear();
返回0;
}
}
是否可以为CLI实用程序编写测试用例?

请参阅教程,其中详细介绍了使用Mockito进行单元测试的基础知识

在高层,您需要:

  • 创建
    Line
    类的实例

  • 为其字段(如
    通信
    标题
    类)创建模拟

  • 对控制台的模拟调用-请参阅
  • 使用所需的值/输出模拟对字段、控制台方法的调用,并测试/断言
    Line
    class
    readLines
    方法为这些值集生成的内容

  • 另一个答案给出了很好的提示,但缺少一个关键点:您可以改进设计,使生产代码更易于测试

    你的问题是你在这里混淆了责任:readLines()应该做的是“核心”函数;然后,需要提供一个命令行界面。你把所有这些都推到一个方法中;这使得测试该方法变得非常困难

    相反,您可以将方法更改为:

    void processLines(List<String> keys, List<String> modules)   { 
    ...
    
    void进程行(列表键、列表模块){
    ...
    
    含义:您不需要在方法的内部询问用户的输入,而是直接向该方法提供该输入。现在您不需要模拟控制台或其他任何东西。您有一个接收两个列表的方法;当使用依赖项注入时,您可以轻松地验证通信/标题是否正确对象可以看到您期望的调用;这取决于您的测试对该方法的输入

    然后,当所有这些都起作用时,您可以编写一个小助手类,如:

    public static void main....
      List<String> keys = new ArrayList<>();
      ... loop code asking user for his input ...
      someLine.processLines(keys, modules);
    
    publicstaticvoidmain。。。。
    列表键=新的ArrayList();
    …循环代码请求用户输入。。。
    进程线(键、模块);
    
    即使这样也可以进行单元测试;但是如果您真的将它保持在这样一个简单的级别上,您可能不需要这样做,因为您的想法是直接在命令上调用它


    长话短说:当您觉得产品代码很难测试时,这是因为“糟糕的设计”首先。当代码很难测试时,也很难修复、增强或重用。您的方法只能在用户提供输入的情况下工作。我的版本也可以直接用于其他场景。正如所说的:这将更容易测试。

    您可以更改
    系统.in
    系统.out流与提供的设置程序。这应该可以提供测试输入,并检查输出是否符合预期。我喜欢您干净可读的代码输入,因此我投了赞成票。但请理解,您的问题接近于“过于宽泛”-你应该总是表现出你解决问题的努力。换句话说:如果你的问题包含了你的一些单元测试想法,那会更好。