The exception testing framework in Java JUnit USES the hands on guide

  • 2020-05-07 19:37:01
  • OfStack

JUnit is a regression testing framework written by Erich Gamma and Kent Beck (regression testing framework). The Junit tests are programmer tests, or white-box tests. The home page of the project: http: / / www junit. org /

With JUnit, test cases are mostly written by inheriting from the TestCase category, and unit tests are written using the testXXX() name.

Writing tests in JUnit really requires only three things:

1.   1 import statement introduces all classes under junit.framework.*.

2.   1 extends statement lets your class inherit from TestCase.

3.   1 constructor that calls super(string).

Functional class MathTool


package com.zj.c01;
public class MathTool { 
 public static int gcd(int num1, int num2) { 
  int r = 0; 
  while (num2 != 0) { 
   r = num1 % num2; 
   num1 = num2; 
   num2 = r; 
  } 
  return num1; 
 } 
} 

The test class MathToolTest


package com.zj.c01;
import junit.framework.TestCase; 
 
public class MathToolTest extends TestCase { 
 public MathToolTest(String name) { 
  super(name); 
 } 
 
 public void testGcd() { 
  assertEquals(5, MathTool.gcd(10, 5)); 
 } 
} 

When we use JUnit test method exception, the easiest way is to use try... To catch exceptions, catch needs to assert the following conditions:
1. Exceptions that do throw
2. Type Class that throws an exception
3. The specific type of exception thrown, 1 check the assertion of the string contained in the message attribute of the exception
So common code you might write like this:


    @Test
    public void testBizException()
{
	    try{
		    Password.validate( "123" );
		    fail( "No exception thrown." );
		   
	}catch ( Exception ex ) {
		    assertTrue( ex instanceof BizException );
		    assertTrue( ex.getMessage().contains( "error" ) );
		   
	}
	   
}


The method being tested here is the Password.validate () method to see if it throws the appropriate exception
fail (" No Exception thrown. ")
Line of code, otherwise if the method being tested does not throw an exception, the use case passes, and you expect the exception to be thrown.
In JUnit 4, you don't have to do this to test for method exceptions. While this can be used to determine whether or not the expected exception is being executed, it still has its drawbacks. catch's method, JUnit cannot give you a detailed reason for the assertion's failure.
So let's see how we can test for exceptions since JUnit 4. Just annotate with @Test (execpted= Exception.class) and refer to the following code:


    @Test( expected = BizException.class )
    public void testBizException()
{
     Password.validate( null );
    
}


If the method being tested throws an BizException type, the assertion succeeds. By the way, @Test (expected = BizException.class) can only determine the type of the exception, and there is no corresponding annotation to assert more specific information about the exception, that is, it cannot determine the message attribute to throw the exception.
So, sometimes we will throw one type of exception several times in one method, but the reason is different, that is, the message information of the exception is different, for example, there will be the following two exceptions when BizException occurs:


  new BizException( " Password must contains at least 6 letters. " )
  new BizException( " Password length less than 15 letters " )

There is a way to assert the message of the exception, for which, since JUnit 4.7, we have been given a more perfect choice, which is the following code:


    @Rule
    public ExpectedException expectedEx = ExpectedException.none();
    @Test
    public void testBizException() throws InvalidPasswordException
{
	    expectedEx.expect( BizException.class );
	    expectedEx.expectMessage( "required" );
	    Password.validate( "" );
	   
}


The above code needs to focus on a few:
1. The ExpectedException variable declaration for the @Rule annotation must be public
2. At @Test, it cannot be written as @Test (expected= BizException.class), otherwise it cannot be tested correctly, i.e
The @Test (expected= BizException.class) method and the expectedEx.expectXxx () method in the test method cannot coexist
The arguments in expectedEx.expectMessage () are Matcher or subString, which means that a regular expression can be used to determine, or determine whether to contain, a substring
4. Another exception that is 1 point heavy, write the test method after expectedEx.expectXxx () method, otherwise it will not test correctly
5. The last one is that as long as the test method directly throws an exception to the method being tested, it does not affect the exception you care about
As mentioned earlier with try... catch's method also correctly detects exceptions, @Test (expected=...) Or @ Rule with try... What is the advantage of catch's comparison? It is clear that JUnit 4's recommendation is concise. What does JUnit tell you when a test fails?
try... When catch test fails with an exception:
As usual:


  java.lang.AssertionError: No exception thrown.
  at org.junit.Assert.fail(Assert.java:91)
  at cc.unmi.PasswordTest.passwordLengthLessThan6LettersThrowsException(PasswordTest.java:20)

Exception type incorrect or exception message incorrect:


  java.lang.AssertionError:
  at org.junit.Assert.fail(Assert.java:91)
  at org.junit.Assert.assertTrue(Assert.java:43)
  at org.junit.Assert.assertTrue(Assert.java:54)
  at cc.unmi.PasswordTest.passwordLengthLessThan6LettersThrowsException(PasswordTest.java:22)

The above can provide us with the correct location of the help is not particularly large
If the test fails at @Test (expected= BizException.class) :


  java.lang.AssertionError: Expected exception: cc.test.BizException
  at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
  at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:110)

Use @Rules ExpectedException to test for exceptions.


  java.lang.AssertionError:
  Expected: (exception with message a string containing  " YES. required "  and an instance of java.lang.NullPointerException)
  got:
  at org.junit.Assert.assertThat(Assert.java:778)
  at org.junit.Assert.assertThat(Assert.java:736)
  at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:114)

In particular, the @Rules ExpectedException method makes it clear why the test failed. What exceptions are expected, what strings are in the exception message, what types of exceptions are actually obtained, and what is message in the exception. With this, you can see how to fix your program.


Related articles: