Java InputStream的单元测试IOException

Java InputStream的单元测试IOException,java,unit-testing,junit,Java,Unit Testing,Junit,有没有一种方法可以不使用PowerMock对以下代码进行单元测试?我们有sonar单元测试代码覆盖范围,它不能识别通过PowerMockRunner测试的代码。所以我正在寻找一种方法来模拟IOException,或者以某种方式使用Mockito来测试这段代码,以便它抛出异常 public void readFile(byte[] bytes) { try (final InputStream inputStream = new ByteArrayInputStream(bytes

有没有一种方法可以不使用PowerMock对以下代码进行单元测试?我们有sonar单元测试代码覆盖范围,它不能识别通过PowerMockRunner测试的代码。所以我正在寻找一种方法来模拟IOException,或者以某种方式使用Mockito来测试这段代码,以便它抛出异常

public void readFile(byte[] bytes) {    
    try (final InputStream inputStream = new ByteArrayInputStream(bytes)) {
       .....
    } catch (IOException e) {
        throw new SystemException("Error reading file");
    }
}



@Test(expected = SystemException.class)
public void testException {
}
任何建议都很好


谢谢。

ByteArrayInputStream的
ByteArrayInputStream
将永远不会引发异常,因此随后您的
尝试
/
捕获是毫无意义的。只需创建
ByteArrayInputStream
并直接使用它并转储异常处理。如果您检查
ByteArrayInputStream
的方法签名,您会注意到异常已被删除,因此不必担心

更新:

您可以像这样安全地与
ByteArrayInputStream进行交互:

public void readFile(byte[] bytes) {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
    ....
    // no need to close the inputStream as it's a NO-OP
}

ByteArrayInputStream
永远不会抛出异常,因此随后您的
try
/
catch
是毫无意义的。只需创建
ByteArrayInputStream
并直接使用它并转储异常处理。如果您检查
ByteArrayInputStream
的方法签名,您会注意到异常已被删除,因此不必担心

更新:

您可以像这样安全地与
ByteArrayInputStream进行交互:

public void readFile(byte[] bytes) {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
    ....
    // no need to close the inputStream as it's a NO-OP
}

您可以使用从字节数组创建并返回
InputStream
的方法来替换
newbytearrayinputstream(bytes)
。如果您为此创建了一个接口,那么

interface InputStreamFactory {
  InputStream from(byte[] bytes);
}
然后,您可以有一个实现,它为生产代码返回
ByteArrayInputStream
,为测试返回抛出
IOException
的对象。也许有一天会有一个
BufferedInputStream
one,依此类推

private final InputStreamFactory factory;

[...]

public void readFile(byte[] bytes) {    
    try (final InputStream inputStream = factory.from(bytes)) {
    ...

您可以使用从字节数组创建并返回
InputStream
的方法来替换
newbytearrayinputstream(bytes)
。如果您为此创建了一个接口,那么

interface InputStreamFactory {
  InputStream from(byte[] bytes);
}
然后,您可以有一个实现,它为生产代码返回
ByteArrayInputStream
,为测试返回抛出
IOException
的对象。也许有一天会有一个
BufferedInputStream
one,依此类推

private final InputStreamFactory factory;

[...]

public void readFile(byte[] bytes) {    
    try (final InputStream inputStream = factory.from(bytes)) {
    ...

您正在使用哪种代码覆盖工具?我已经成功地通过使用Cobertura和JaCoCo的PowerMock测试了代码中的SonarQube单元测试覆盖率。如果没有PowerMockito,就无法进行模拟,并且任何输入都不会使用
ByteArrayInputStream
导致异常。我认为您最好的选择是使用@tddmonkey的答案。它没有回答你最初的问题,但我认为它解决了你的实际问题。编辑:查看@superfav的答案,了解将调用移动到方法以利用Mockito的一般示例。@toddunlap我使用的是SonarQube 5.2版,它完全忽略了标记为@Runwith(PowerMockRunner.class)的测试的单元测试覆盖率,但是什么生成了单元测试覆盖率数据?您确定它实际上是在生成数据,而不仅仅是显示数据吗?根据我的经验,SonarQube读取其他工具生成的覆盖率数据。使用Cobertura,您不必做任何特殊的事情就可以让它与PowerMock一起工作。对于JaCoCo,有一些选项,但我通常会在Maven构建中添加一个覆盖率配置文件,该配置文件以与PowerMock兼容的方式配置JaCoCo,以便覆盖率数据覆盖PowerMock代码,我可以在SonarQube中看到这一切。您使用的是哪种代码覆盖率工具?我已经成功地通过使用Cobertura和JaCoCo的PowerMock测试了代码中的SonarQube单元测试覆盖率。如果没有PowerMockito,就无法进行模拟,并且任何输入都不会使用
ByteArrayInputStream
导致异常。我认为您最好的选择是使用@tddmonkey的答案。它没有回答你最初的问题,但我认为它解决了你的实际问题。编辑:查看@superfav的答案,了解将调用移动到方法以利用Mockito的一般示例。@toddunlap我使用的是SonarQube 5.2版,它完全忽略了标记为@Runwith(PowerMockRunner.class)的测试的单元测试覆盖率,但是什么生成了单元测试覆盖率数据?您确定它实际上是在生成数据,而不仅仅是显示数据吗?根据我的经验,SonarQube读取其他工具生成的覆盖率数据。使用Cobertura,您不必做任何特殊的事情就可以让它与PowerMock一起工作。对于JaCoCo,有一些选项,但我通常会在Maven构建中添加一个覆盖率配置文件,该配置文件以与PowerMock兼容的方式配置JaCoCo,以便覆盖率数据覆盖PowerMock代码,我可以在SonarQube中看到这一切。
ByteArrayInputStream
在自动关闭时可能会抛出一个
IOException
。Eclipse说,inputStream上的自动关闭()调用引发了
未处理的异常类型IOException
。不,它不会-方法是noop。没有理由引用Javadoc关闭一个ByteArrayInputStream。关闭一个ByteArrayInputStream没有任何效果。你是正确的,但是你仍然必须处理异常。你没有!OP显式地将其用作
ByteArrayInputStream
而不是通用的
InputStream
,因此根本不需要进行任何异常处理。它可以从代码中删除。
ByteArrayInputStream
在自动关闭时可能会抛出一个
IOException
。Eclipse说,inputStream上的自动关闭()调用引发了
未处理的异常类型IOException
。不,它不会-方法是noop。没有理由实际关闭一个
ByteArrayInputStream
引用Javadoc-
关闭一个ByteArrayInputStream没有效果