Search code examples
javajunitjunit4

assertEquals doesn't show errors when the test is expecting exceptions


I recently started to work with Junit.

I have a function that receives a line with values taken from a txt file, and returns instances with that values.

Everytime that function receives wrong values, I throw an exception.

My test method is verifying if the exceptions are working fine, and if the values returned by the instance are right.

@Test(expected = StudentException.class)
public void testImportStudent() {
    String txtline = "1, Name, Name"; //Wrong, It should be 1, Name
    Source test = studentMain.importStudent(txtline); //Throw error
    txtline = "1, Name"; //Right
    test = percursoGestor.importSource(line); //Test passed
    assertEquals("Error inserting ID", 3, test.getStudentID()); //Test ignores this line
    assertEquals("Error inserting Name", "Nothing", test.getStudentName()); //Test ignores this line
}

So, my test checks if the error was thrown, but ignores the assertequals, even though I put a value different than expected, the test passes. Because I'm expecting for an exception to be thrown.

What am I doing wrong?


Solution

  • You have annotated your test method with expected = StudentException.class.

    What this basically does is putting a try-catch block around your whole method:

    @Test(expected = StudentException.class)
    public void testImportStudent() {
        try {
            String txtline = "1, Name, Name";
            Source test = studentMain.importStudent(txtline); //Throw error
            txtline = "1, Name";
            test = percursoGestor.importSource(line);
            assertEquals("Error inserting ID", 3, test.getStudentID());
            assertEquals("Error inserting Name", "Nothing", test.getStudentName());
        } catch (Exception e) {
            // verify exception
        }
    }
    

    And as usually: Nothing is executed after an exception is thrown.

    The clean way would be to have two separate methods:

    @Test(expected = StudentException.class)
    public void testImportStudent_incorrectInput() {
        String txtline = "1, Name, Name";
        Source test = studentMain.importStudent(txtline);
    }
    
    @Test
    public void testImportStudent_correctInput() {
        String txtline = "1, Name";
        Source test = percursoGestor.importSource(line);
        assertEquals("Error inserting ID", 3, test.getStudentID());
        assertEquals("Error inserting Name", "Nothing", test.getStudentName());    
    }
    

    If you really want to test multiple cases in one method (which you probably don't), then you can work with try-catch yourself:

    @Test
    public void testImportStudent() {
        String txtline = "1, Name, Name";
        Source test;
        try {
            test = studentMain.importStudent(txtline);
            // Make sure that the test fails when no exception is thrown
            fail();
        } catch (Exception e) {
            // Check for the correct exception type
            assertTrue(e instanceof StudentException);
        }
        // Other checks
        txtline = "1, Name";
        test = percursoGestor.importSource(line);
        assertEquals("Error inserting ID", 3, test.getStudentID());
        assertEquals("Error inserting Name", "Nothing", test.getStudentName());
    }