首页 > 解决方案 > 如何使用 Mockito/PowerMockito 触发 IOException 进行单元/集成测试

问题描述

我正在对以下代码进行测试,但我无法让这种方法抛出 IOException,因此我可以获得 100% 的覆盖率。我试图模拟 CharArrayReader、StringWriter 类但无济于事。将不胜感激任何帮助!

测试类

public static final String getValue(String content) {
    if (content == null) return null;
    CharArrayReader reader = new CharArrayReader(content.toCharArray());
    StringWriter writer = new StringWriter();
    try {
        int c;
        while ((c = reader.read()) != -1) {
            if (isChinese((char)c)) {
                writer.write(c);
            } else {
                if ( (char)c > 0x20 && (char)c < 0x7f ) {
                    writer.write(c);
                } else {
                    writer.write(' ');
                }
            }
        }
    } catch (IOException e) {
        return null;
    } finally {
        reader.close();
    }
    return writer.toString();
}

我的尝试

@Test
public void getValue_Exception() throws IOException {
    String content = "asd";
    char[] chara = null;
    CharArrayReader reader = mock(CharArrayReader.class);
    when(content.toCharArray()).thenReturn(chara);
    
    when(reader.read()).thenThrow(IOException.class);
    StringWriter writer = mock(StringWriter.class);
    doThrow(IOException.class).when(writer).write(anyInt());


    spyController.getValue(content);
}

标签: javaunit-testingmockitointegration-testingpowermockito

解决方案


CharArrayReader::read抛出的唯一场景IOException是流关闭时。在您的示例中,这似乎是不可能的。

不过,如果您真的想获得 100% 的覆盖率,或者只是确保您的班级在出现意外情况时表现良好,我的建议是为您的读者创建一个工厂,例如:

class ReaderFactory {
    Reader create(String content) {
        return new CharArrayReader(content.toCharArray());
    }
}

有了这个类,您可以在代码中使用它并模拟该create方法。这样您就可以控制Reader在您的测试用例中使用的实例。


推荐阅读