我有一个类,它读取文件并使用扫描仪接收用户输入,如果扫描仪等于该文件中某一行的一部分,它将显示来自同一行的字符串。
我将如何为此创建一个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);
}
答案 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
}