0

Setup:

  • java 1.8
  • JUnit 4.8.1

Java is not really my thing. But still I'm playing around with JUnit. I wish to write a test case of which he outcome is an exception.

I followed some examples I found with no luck

import biblioteca.exception.InvalidAuthorException;
import biblioteca.util.Validator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 *  Test
 */
public class MyTest  {
    @Rule
    public ExpectedException exception = ExpectedException.none();

    @Test
    public void testValidator()
    {
        assertTrue(Validator.isAlphaNumeric("A1"));
        assertFalse(Validator.isAlphaNumeric("><"));
        assertTrue(Validator.validateLength("vasile", 2, 64));
        assertFalse(Validator.validateLength("vasile", 24, 64));
        assertTrue(Validator.containsAtLeastOneLetter("1234a"));
        assertFalse(Validator.containsAtLeastOneLetter("1234"));
    }
    @Test
    public void testException() {
        Validator.validateAuthor("123");
        exception.expect(InvalidAuthorException.class);
    }
}

This approach throws an error

enter image description here

This approach does not result in the desired outcome (I want the test to pass as I'm expecting the error)enter image description here

What am I missing?

vitoriodachef
  • 113
  • 10
  • 5
    Please put the text code not pics of it. – ChiefTwoPencils Apr 15 '18 at 16:34
  • @ChiefTwoPencils done – vitoriodachef Apr 15 '18 at 16:37
  • 1
    Also your tests are kind of bad. This gets into personal preference, but I was always taught to test exactly one thing in a test case. The reason is that if you have a test failure, you don't want to have to spend a lot of time figuring out what just failed. The test should be simple so that the error is obvious. Unit tests are meant to speed developer progress and slowing down to use a debugger (or similar) to figure out what cause a unit test to fail tends to promote the opposite of "speed." – markspace Apr 15 '18 at 16:38

1 Answers1

0

You just need to reverse the order of

   Validator.validateAuthor("123");

and

   exception.expect(InvalidAuthorException.class);

If

Validator.validateAuthor("123");

throws an exception, your test function ( like any Java function ) will terminate immediately on that uncaught exception,so the exception.expect will never happen.

Another way to write a test which expects exceptions is this way:

@Test
public void testException() {
    boolean exceptionOccurred = false;
    try 
     {
      Validator.validateAuthor("123");
     }
    catch( InvalidAuthorException e )
    {
      exceptionOccurred  = true;
    }
   Assert.assertTrue( "Error: Expected test to throw an InvalidAuthorException",exceptionOccurred );    
}

It's much more verbose, and it's less clear that the test is a Negative test, but it has one important advantage, the exception does not terminate the test function, so you can do other things like logging and further checks on the failure state, and it's the only way in which you can check the actual exception message as follows:

@Test
public void testException() {
    try 
     {
      Validator.validateAuthor("123");
      Assert.fail("Error: Expected to get an InvalidAuthorException");  // Necessary for failing the test if there is no exception. Without this the test will pass
     }
    catch( InvalidAuthorException e )
    {
       Assert.assertEquals("Bad Author", e.getMessage());     
    }
}

Yet another way, ( before rules were introduced into JUnit ) is this way:

@Test( expected = InvalidAuthorException.class )
public void testException() {
      Validator.validateAuthor("123");
}

Its nice because it is very concise, and it's clear that it's a negative test, will fail your test if no exception occurs, and will pass your test when the exception happens, but you won't be able to add any more test statements in that test function because once again, the exception terminates the test function, so no way to check the exception message.

Gonen I
  • 5,576
  • 1
  • 29
  • 60
  • Indeed, the expect cannot be reached if an exception is thrown. – ChiefTwoPencils Apr 15 '18 at 16:47
  • I have to take my vote back due to the try/catch example. That's *a way* but typically a poor choice. It adds unnecessary boilerplate code and eliminates any meaningful information that would come with the exception. For example, your test fails on the Assert which will be the beginning of the stack trace. – ChiefTwoPencils Apr 15 '18 at 16:57