如何使用扫描仪对JUnit测试方法?

时间:2015-12-07 17:32:37

标签: java junit java.util.scanner

我有一个类,它读取文件并使用扫描仪接收用户输入,如果扫描仪等于该文件中某一行的一部分,它将显示来自同一行的字符串。

我将如何为此创建一个Junit测试方法?

以下是我想要测试方法的一些代码:

Scanner Input = new Scanner(System.in);
    String name = Input.nextLine();

    BufferedReader br;
   try{
       br = new BufferedReader(new FileReader(new File(filename)));
       String nextLine;
       while ((nextLine = br.readLine()) != null)
       {
           if (nextLine.startsWith("||"))
           {
                int f1 = nextLine.indexOf("*");
                int f2 = nextLine.indexOf("_");
                fName = nextLine.substring(f1+1, f2);
                   if (name.equals(fname))
                   {
                        String[] s1 = nextLine.split("_");
                        String sName = s1[1];
                        System.out.println(sName);
                   }
           }
       }

我的数据文件看起来像这样

||
*Jack_Davis
*Sophia_Harrolds

我试图在我的测试方法中使用此代码

@Test
public void testgetSurname() {
    System.out.println("get surname");
    String filename = "";
    String expResult = "";
    String result = fileReader.getSurname(filename);
    assertEquals(expResult, result);

    filename = "datafiles/names.txt";
    String data = "Jack";
    InputStream stdin = System.in;
    try{
      System.setIn(new ByteArrayInputStream(data.getBytes()));
      Scanner scanner = new Scanner(System.in);
      System.out.println(scanner.nextLine());
    } finally {
      System.setIn(stdin);
      expResult = "Davis";
    }
    String result = fileReader.getSurname(filename);
    assertEquals(expResult, result);                
}

2 个答案:

答案 0 :(得分:3)

一种方法:

第1步

重构代码,以便Scanner是传递给方法的参数之一。

第2步

对于您的测试,请使用构造函数Scanner(File file)Scanner(String source)来提供“用户输入的内容” - 在现实世界中(来自您创建的main() {{1} }}

重构你的代码以获得Scanner(System.in)然后使用Mocking框架(我喜欢Mockito)来模拟该方法并返回你的String-readyped protected Scanner getScanner() { }(参见步骤2)

请求的示例(重构)

Scanner

现在你已经把小问题打破了。单元测试现在仅用于单个方法 - 因此用于测试从Scanner读取一行,一个用于测试匹配逻辑,一个用于正确的文件迭代。

答案 1 :(得分:2)

试试这个例子:

您可以通过自动模拟控制台来增强它(见下文)

"graphs": [
    {
        "fillAlphas": 1,
        "id": "AmGraph-1",
        "labelPosition": "right",
        "labelText": "[[value]]",
        "title": "graph 1",
        "type": "column",
        "valueField": "column-1"
    },
    {
        "fillAlphas": 1,
        "id": "AmGraph-2",
        "labelPosition": "right",
        "labelText": "[[value]]",
        "title": "graph 2",
        "type": "column",
        "valueField": "column-2"
    }
],

如果要自动化控制台输入,请使用:

礼貌:JUnit: How to simulate System.in testing?

@Test
public void test_scan() throws Exception
{
Myclass myobject=new myobject(); // with args

myobject.load(filename); // you must definie the filename

String result=myobject.scaninput_and_compare(); // you must use scan in, and compare

if (!result.equals(what_I_am_expecting) throw new Exception("EXCEPTION scaninput_and_compare"); 

// If you arrive here, it's OK
}

小心内部捕获异常,完成"好" System.in单独进行测试是好的,对于好几个,你应该验证。

使用您的代码:

String data = "What_I_could_put_in_console";
InputStream stdin = System.in;
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.setIn(stdin);

更好的设计和测试更容易:将System.in的扫描仪与文件解析分开。只需使用(filename,fname)执行一个函数,它将直接测试:

public String scaninput_and_compare(String filename)
{
Scanner Input = new Scanner(System.in);
String name = Input.nextLine();

BufferedReader br;
 try{
   br = new BufferedReader(new FileReader(new File(filename)));
   String nextLine;
   while ((nextLine = br.readLine()) != null)
   {
       if (nextLine.startsWith("||"))
       {
            int f1 = nextLine.indexOf("*");
            int f2 = nextLine.indexOf("_");
            fName = nextLine.substring(f1+1, f2);
               if (name.equals(fname))
               {
                    String[] s1 = nextLine.split("_");
                    String sName = s1[1];
                    return sName;
               }
       }
   }
// NO GOOD
return "lose";
}


@Test
public void test_scan() throws Exception
{
Myclass myobject=new myobject(); // with args

String filename="good_filename";

// MOCK System.in
String data = "Jack";
InputStream stdin = System.in;
System.setIn(new ByteArrayInputStream(data.getBytes()));

String result=myobject.scaninput_and_compare(filename); // you must use scan in, and compare

// RESTABLISH System.in
Scanner scanner = new Scanner(System.in);
System.setIn(stdin);

if (!result.equals("Davis") throw new Exception("EXCEPTION scaninput_and_compare"); 

// If you arrive here, it's OK
}