我想为解析器编写单元测试,并希望检查它是否正确地为列表中的所有输入字符串抛出异常.现在据我所知,JUnit的标准方法是为每个案例编写一个单独的测试方法:
public final class ParseFailureTest1 { @Test(expected = ParseException.class) public void testParseFailure1() throws Exception { Parser.parse("[1 2]"); // Missing comma } @Test(expected = ParseException.class) public void testParseFailure2() throws Exception { Parser.parse("[1, 2,]"); // Additional commas } }
但是,由于我想将相同的测试应用于20或50个不同的字符串,这似乎是不切实际的.
另一种方法是使用catch
块显式检查异常:
public final class ParseFailureTest2 { @Test public void testParseFailure() throws Exception { Listdocuments = Arrays.asList( "[1 2]", // Missing comma "[1, 2,]"); // Additional commas for (String document : documents) { try { Parser.parse(document); throw new AssertionError("Exception was not thrown"); } catch (ParseException e) { // Expected, do nothing. } } } }
但这很容易出错,我不会得到任何关于预期的异常的信息,如果抛出了不同的异常,它将被视为测试错误,而不是失败.
我的解决方案是使用类似expectException
下面的方法:
public final class ParseFailureTest3 { @Test public void testParseFailure() throws Exception { Listdocuments = Arrays.asList( "[1 2]", // Missing comma "[1, 2,]"); // Additional commas for (final String document : documents) { expectException(ParseException.class, new TestRunnable() { @Override public void run() throws Throwable { Parser.parse(document); } }); } } public static void expectException(Class extends Throwable> expected, TestRunnable test) { try { test.run(); } catch (Throwable e) { if (e.getClass() == expected) { return; // Expected, do nothing. } else { throw new AssertionError(String.format("Wrong exception was thrown: %s instead of %s", e.getClass(), expected), e); } } throw new AssertionError(String.format("Expected exception was not thrown: %s", expected)); } public interface TestRunnable { void run() throws Throwable; } }
在JUnit框架或相关库中是否存在用于该目的的方法,或者您是否会针对该问题建议不同的方法(或我拒绝的方法之一)?