关于java:Junit已经有try-catch子句的方法的测试用例

Junit Test case of method that already has a try-catch clause

我正在尝试为类ErParser中的方法setTrailer()编写测试用例。 setTrailer()具有try-catch子句,并且在其中一个catch子句中,它捕获NullPointerException。 我正在尝试为setTrailer()抛出并捕获NullPointerException的情况编写Junit测试,但测试用例仍然失败。 是因为我已经在方法本身中捕获了异常吗? 我应该在测试用例中捕获异常吗?

测试用例:

1
2
3
4
5
6
7
public class TestERParser {
    @Test(expected=NullPointerException.class)
    public void nullSetTrailer() {
        ERParser recCurrParse = new ERParser();
        recCurrParse.setTrailer(null);
    }  
}

ERParser类中的setTrailer()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ERParser {
private static final String TRAILER_E ="GRAND TOTAL";
private static final String TRAILER_R ="TRAILER";
public String trailerRecord;

/**
 * Constructs an ERParser object.
 */

public ERParser() {
    this.trailerRecord = null;
    this.trailerVals = null;
}
/**
 * Populates the trailerRecord field with the summary (trailer) record of the input file.
 * @param file  Input file
 * @throws NullPointerException, FileNotFoundException, IOException
 */

public void setTrailer(File file) {
    try {
        FileReader fReader = new FileReader(file);
        BufferedReader bReader = new BufferedReader (fReader);
        String currLine = new String();
        readLoop:
            while (bReader.ready()) {
                currLine = bReader.readLine();
                if (currLine.contains(TRAILER_E) || currLine.contains(TRAILER_R)) {
                    break readLoop;
                }
            }
        this.trailerRecord = currLine.trim();
        System.out.println("From setTrailer():" + this.trailerRecord);
        fReader.close();
        bReader.close();
    } catch (NullPointerException exception) {
        exception.printStackTrace();
    } catch (FileNotFoundException exception) {
        exception.printStackTrace();
    } catch (IOException exception) {
        exception.printStackTrace();
    }
}
}


正如您所怀疑的那样,您正在捕获代码中的NPE并且它没有被传播。如果您希望用户捕获此异常,则应删除此代码并使用throws将方法装饰到适当的类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void setTrailer(File file) throws Exception {
        FileReader fReader = new FileReader(file);
        BufferedReader bReader = new BufferedReader (fReader);
        String currLine = new String();
        readLoop:
            while (bReader.ready()) {
                currLine = bReader.readLine();
                if (currLine.contains(TRAILER_E) || currLine.contains(TRAILER_R)) {
                    break readLoop;
                }
            }
        this.trailerRecord = currLine.trim();
        System.out.println("From setTrailer():" + this.trailerRecord);
        fReader.close();
        bReader.close();
}

由于您的代码现在抛出一个已检查的Exception,您需要稍微更新您的Junit方法,以捕获已检查的异常

1
2
3
4
5
   @Test(expected=NullPointerException.class)
    public void nullSetTrailer() throws Exception {
        ERParser recCurrParse = new ERParser();
        recCurrParse.setTrailer(null);
    }

我们可以争论这个catch块是否意味着处理了异常。我认为仅仅打印堆栈跟踪不会处理任何事情。最好在方法签名中添加throws子句,让客户决定如何处理异常。

如果方法是以这种方式编写的,那么由你自己来测试它。如果这是第三方库,您将无法选择。

编写抛出异常的测试;成功意味着trailerRecord设置为null

您的代码有另一个缺陷:关闭finally块中的流。您可能无法正确关闭输入流。


在您的测试用例中,期待一个NullPointerException类。如果你抓住它,调用者类将无法获得它。因此,您可以删除try / catch块,也可以在打印stacktrace后重新抛出异常:

1
2
3
4
catch (NullPointerException exception) {
        exception.printStackTrace();
        throw new NullPointerException();
    }