繁体   English   中英

测试构造方法中抛出的异常未按预期运行

[英]Test for thrown exception in constructor method not behaving as expected

我有以下代码从我试图为其编写单元测试的 csv 文件中读取数据。 我不确定如何与 go 联系。

public class BudgetTags implements BudgetTagsList{
    // State variables
    private Set<String> tags = new TreeSet<>();
    private String tag_file_path;

    public BudgetTags(String tag_file_path){
        //Retrieve tags from tag file
        this.tag_file_path = tag_file_path;
        this.retrieveTags();
    }
public void retrieveTags() {
        String line = "";
        try{
            // Begin reading each line
            BufferedReader br = new BufferedReader(new FileReader(this.tag_file_path ));
            while((line = br.readLine()) != null){
                String[] row = line.split(",");
                this.tags.add(row[0]); //Assume correct file format
            }
            br.close();
        } catch (IOException e){
            System.out.println("Fatal exception: "+ e.getMessage());
        }
    }
}

请注意方法retrieveTags(); 不允许我指定额外的FileNotFoundException因为它扩展了IOException 它正在通过以下方式进行测试:

@Test
    @DisplayName("File name doesn't exist")
    void testRetrieveTag3() {
        String path = "test\\no_file.csv";

        //Instantiate new tags object
        BudgetTags tags = new BudgetTags(path);
        IOException thrown = assertThrows(IOException.class, () -> tags.retrieveTags());
    }

变量path不存在,所以我希望测试能够捕获 IOException(尽管我更喜欢 FileNotFoundException)。 当我运行这个特定的测试时,我收到一个AssertionFailedError我如何重构我的测试,以便它在实例化新标签 object 时捕获 FileNotFoundException,因为在生成新标签 object 时调用 retrieveTags()?

retrieveTags()方法不允许我指定

您的assertThrows测试失败,因为构造函数不可能抛出IOException 首先,它是一个已检查的异常,这意味着构造函数和方法都需要一个throws IOException子句。 其次,你捕捉到异常; 它没有被抛出方法。

根据您的测试,它应该看起来更像这样:

public class BudgetTags implements BudgetTagsList {

    private final Set<String> tags = new TreeSet<>();
    private String tagFilePath;

    public BudgetTags(String tagFilePath) throws IOException {
        this.tagFilePath = tagFilePath;
        retrieveTags(); // can throw IOException
    }

    public void retrieveTags() throws IOException {
        // note: use try-with-resources to handle closing the reader
        try (BufferedReader br = new BufferedReader(new FileReader(tagFilePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                String row = line.split(",");
                tags.add(row[0]);
            }
        }
        // don't catch the exception; your test indicates you want it
        // thrown out to the caller
    }
}
class BudgetTagsTests {

    @Test
    @DisplayName("File does not exist")
    void testRetrieveTags3() {
        String tagFilePath = "test/no_file.csv";

        // note: we need to test on the constructor call, because you call
        // 'retrieveTags()' in it.
        assertThrows(FileNotFoundException.class, () -> new BudgetTags(tagFilePath));
    }
}

通过传递FileNotFoundException.class ,如果抛出任何其他IOException ,测试将失败。


无论如何,您不应该像现在这样捕获IOException 是的,您将其记录下来,这意味着如果您查看日志,您会发现出现了问题。 但是其他代码不会知道出了什么问题。 对于该代码,文件中似乎根本就没有标签。 通过将IOExceptionretrieveTags()的调用者,您可以让调用者根据需要对异常做出反应。 如果调用成功,但标签为空,则它知道文件存在但只是没有标签。

另外,你说:

请注意方法retrieveTags(); 不允许我指定额外的FileNotFoundException因为它扩展了IOException

我不确定您从该语句中到底尝试了什么,但是即使您也捕获了更一般的异常,也可以捕获更具体的异常。 只是 catch 块的顺序很重要:

try {
    somethingThatThrowsIOException();
} catch (FileNotFoundException ex) {
    // do something special for when the file doesn't exist
} catch (IOException ex) {
    // handle general exception
}

更具体的异常必须在更一般的异常之前被捕获。

该方法实际上不是抛出异常而是捕获它。 您实际需要测试的是您的 catch 块是否已执行。 如果您捕获异常时只想打印错误, 测试 system.out可以帮助您断言打印语句

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM