gpt4 book ai didi

java - 编写 Junit 测试以覆盖异常和 catch block

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:05:24 26 4
gpt4 key购买 nike

我已经为以下功能编写了 Junit 测试用例。检查 JACOCO 测试覆盖率时。它显示只有 try block 被测试用例覆盖。我是编写测试用例的新手。如何在测试用例中覆盖异常和 catch block

这是一个方法

  public static List<Student> readCsvFile(String fileName)
{

BufferedReader fileReader = null;

//logic to read file
}
catch (Exception e)
{
System.out.println("Error in CsvFileReader !!!");
e.printStackTrace();
} finally
{
try
{
fileReader.close();
} catch (IOException e)
{
System.out.println("Error while closing fileReader !!!");
e.printStackTrace();
}
}
return students;
}

和测试方法

@Test
public void ReadCsvFileTest()
{
String fileName = "test.csv";
List<Student> result = new ArrayList<Student>();
result = CsvFileReader.readCsvFile(fileName);

Student student1 = null;

Iterator<Student> it = result.iterator();
while (it.hasNext())
{
Student s = it.next();
if ("471908US".equals(s.getId()))
{
student1 = s;
break;
}
}

assertTrue(student1 != null);
}

最佳答案

在这种情况下,您可能经常会考虑为您的类引入额外的依赖项。这是我的意思,举一个粗略的例子。为读者创建一个工厂:

interface BufferedReaderFactory
{
public BufferedReader createBufferedReader(String fileName) throws IOException;
}

那么您将拥有一个几乎不需要任何测试的简单实现,例如类似的东西:

class BufferedReaderFactoryImpl implements BufferedReaderFactory
{
@Override
public BufferedReader createBufferedReader(String fileName) throws IOException
{
return new BufferedReader(new FileReader(fileName));
}
}

然后你必须找到一种方法将这种依赖关系注入(inject)你的类中。我通常使用 Guice在我的日常工作中,但您可以尝试一些简单的方法,例如使用构造函数注入(inject)并使您的方法非静态。这是一个例子:

class CsvFileReader
{
private final BufferedReaderFactory factory;

public CsvFileReader(BufferedReaderFactory factory)
{
this.factory = factory;
}

public List<Student> readCsvFile(String fileName)
{

BufferedReader fileReader = null;
try
{
fileReader = factory.createBufferedReader(fileName);
...
}
catch(IOException e)
{
...
}
finally
{
...
}
return new LinkedList<>();
}
}

使用类似 Mockito 的模拟框架此类在 IOException 情况下的行为现在更容易测试(请注意,您还可以返回从工厂抛出异常的模拟)。这是一个示例:

@RunWith(MockitoJUnitRunner.class)
public class MyTest
{
@Mock
private BufferedReaderFactory mockFactroy;

@Test
public void testIOException() throws IOException
{
String ivalidFileName = "invalid.txt";
//throw exception in case that invalid file name is passed to the factory
Mockito.when(mockFactroy.createBufferedReader(ivalidFileName)).thenThrow(new IOException("Hello!"));

CsvFileReader csvFileReader = new CsvFileReader(mockFactroy);
//invoke with a factory that throws exceptions
csvFileReader.readCsvFile(ivalidFileName);
//...
//and make a sensible test here, e.g. check that empty list is returned, or proper message is logged, etc.
}
}

当然,您可以在没有 Mockito 的情况下通过实现测试工厂来做到这一点。但这更麻烦,尤其是在更复杂的用例中。一旦抛出 IOException,您将获得 JaCoCo 的适当覆盖率报告。

还要注意提到的 JaCoCo 的限制 here , 在部分 中,有异常的源代码行显示没有覆盖。为什么?

关于java - 编写 Junit 测试以覆盖异常和 catch block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41110390/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com