Unit test Best Practices when testing Exceptions [closed]

℡╲_俬逩灬. 提交于 2020-01-07 09:34:12

问题


So I've been unit testing an android application, and while there are cases that I test with fail scenarios, I don't test them quite the way this answer is suggesting (Try catch in a JUnit test).

I test it the way it shows on the code below. The answer is suggesting that you should have on test method signature the "throws Exception", since if it actually throws an exception you don't expect, it will fail the test. However i tried it with and without that piece of code, and it fails the same way. The answer provided above, also approaches this kind of test with the use of "rule", which i haven't used, since everything i need i have them inside my try catch block, and the instantiations are done inside a @Before method.

@Test
public void testMethod() {
   try{
   //code that will throw exception
   fail("Exception was not thrown");
   } catch (/* types of exceptions */) {
   //my asserts
   }
}

What I'm after is which approach is considered "best practice" and the reason behind it.


回答1:


There's the expected attribute of the @Test annotation to define test cases that check if specific exceptions get raised. Alternatively there's the @Rules annotation for more specific control and a somewhat deprecated "try-catch" idiom. For samples see this and the junit wiki.

@Test(expected = IllegalArgumentException.class)



回答2:


Since this was tagged with JUnit4 my preferred is to use the expected attribute of the @Test annotation

@Test(expected = NullPointerException.class)

However, if you need to check further properties of the thrown exception, you can use ExpectedException, it's quite powerful:

@Rule
public ExpectedException exceptionRule = ExpectedException.none();

@Test
public void whenExceptionThrown_thenRuleIsApplied() {
    exceptionRule.expect(NumberFormatException.class);
    exceptionRule.expectMessage("For input string");
    Integer.parseInt("1a");
}

I would suggest using JUnit 5 however, where you can make use of Java 8 constructs such as passing a Lambda for the check, which makes your code quite declarative and concise.

Good article for both JUnit 4 and JUnit 5: https://www.baeldung.com/junit-assert-exception




回答3:


Personally I use the assertThrows and assign the result to a Throwable so I can check the message. The reason for doing this is, for example, when I need to check validations which return IllegalArgument, I can check if the message is the expected one for the field is missing.

@Test
public void testSomething_shouldThrowException() {

  String expectedMessage = "Exception running the method";

  Throwable exception = Assertions.assertThrows(YourException.class, () 
    -> {
      bean.doSomething(dummyRequest);
    });

  Assert.assertEquals(expectedMessage, exception.getMessage());
}


来源:https://stackoverflow.com/questions/58337403/unit-test-best-practices-when-testing-exceptions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!