JUnit测试预期exception的正确方法

大家好,我想知道这种测试我的exception是否正常,我有这个例外我需要抛出第二个测试注释,我接收结果是一个红色邪恶的条,一个成功和一个失败,你可以猜到失败是我关心的,我有失败(); 但原因是因为我读到了测试exception的方法,现在我很困惑。

此外,我不得不说im willin得到绿色条,因为我期待exception,但我不知道失败是否是正确的方式来看到预期的exception的答案。

如果您有任何建议,我将不胜感激

@Before public void setUp() throws Exception { LogPack.logPacConfig(Constants.LOGGING_FILE); gtfri = "+RESP:GTFRI,380502,869606020101881,INCOFER-gv65,,10,1,1,0.0,0,888.1,-84.194560,9.955602,20170220074514,,,,,,0.0,,,,100,210100,,,,20170220074517,40A2$"; weirdProtocol = "+RESP:GRI,380502,869606020101881,INCOFER-gv65,,10,1,1,0.0,0,888.1,-84.194560,9.955602,20170220074514,,,,,,0.0,,,,100,210100,,,,20170220074517,40A2$"; factory = new LocomotiveFactory(); } @Test public void GTFRICreationTester_shouldPass() throws TramaConProtolocoloDesconocido { assertTrue(factory.createLocomotive(gtfri, false, new Date()) instanceof LocomotiveGTFRI); } @Test(expected = TramaConProtolocoloDesconocido.class) public void GTFRICreationTester_shouldFail() { try { factory.createLocomotive(weirdProtocol, false, new Date()); fail("Expected an TramaConProtolocoloDesconocido"); } catch (TramaConProtolocoloDesconocido e) { //assertSame("exception thrown as expected", "no se conoce el protocolo dado para la creacion de este factory", e.getMessage());; } } 

测试预期exception有3种最常用的方法:

第一种方法是最常用的方法,但您只能使用它来测试预期exception的类型。 如果不抛出ExceptionType则此测试将失败:

 @Test(expected = ExceptionType.class) public void testSomething(){ sut.doSomething(); } 

此外,您无法使用此方法指定失败消息

更好的选择是使用ExpectedException JUnit @Rule 。 在这里,您可以为预期的exception断言更多

 @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testSomething(){ thrown.expect(ExceptionType.class); thrown.expectMessage("Error message"); thrown.expectCause(is(new CauseOfExeption())); thrown.reportMissingExceptionWithMessage("Exception expected"); //any other expectations sut.doSomething(); } 

第三个选项将允许您执行与使用ExpectedException @Rule相同的操作,但所有断言都应手动编写。 但是,此方法的优点是您可以使用任何自定义断言和所需的任何断言库:

 @Test public void testSomething(){ try{ sut.doSomething(); fail("Expected exception"); } catch(ExceptionType e) { //assert ExceptionType e } } 

您可以使用ExpectedException ,它可以为您提供有关预期抛出的exception的更精确信息,并具有validation错误消息的能力,如下所示:

 import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; public class TestClass { @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void GTFRICreationTester_shouldFail() { expectedException.expect(TramaConProtolocoloDesconocido.class); factory.createLocomotive(weirdProtocol, false, new Date()); } } 

要更多地了解它,你可以参考我在这里写的博客 – 预期的exception规则和模拟静态方法 – JUnit

您不需要使用try-catch Exception

 @Test(expected = TramaConProtolocoloDesconocido.class) public void GTFRICreationTester_shouldFail() { factory.createLocomotive(weirdProtocol, false, new Date()); } 

如果我们假设factory.createLocomotive(weirdProtocol, false, new Date())在应用引发exception的方案时抛出exception。

 void createLocomotive(param...) { //something... throw new TramaConProtolocoloDesconocido(); } 

如果您使用的是java 8,我建议您去AssertJ库

 public void GTFRICreationTester_shouldFail() { assertThatExceptionOfType(EXCEPTION_CLASS).isThrownBy(() -> { factory.createLocomotive(weirdProtocol, false, new Date()) }) .withMessage("MESSAGE") .withMessageContaining("MESSAGE_CONTAINING") .withNoCause(); } 

使用该解决方案,您可以在一个validationexception类型,消息等。

如需更多阅读,请查看: http : //joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#exception-assertion