简体   繁体   中英

catching an exception after doThrow JUNIT

I have a JUnit test where I am testing a method with null arguments. If the argument /arguments are null, then I would throw a NullPointerException. The method by itself will just throw an IOException. I am using doThrow on mock object of the class but it seems to me that I am losing the exception in the doThrow() construct and I am unable to catch it. Additionally, I strictly do not want to use a try catch in my unit tests. So I am using @Rules for the same. Here is the code snippet:

public class TableTest {

@Rule
public ExpectedException exception = ExpectedException.none();
private static Table spyTable;

@Test
public void testCreateTableWithNullTableName_throwsIOEXception() throws IOException {
    final String tableName = null;
    mockConfig = mock(Configuration.class);
    spyPersonTable = spy(new PersonTable());
    doThrow(new IllegalArgumentException()).when(spyPersonTable).createTable(tableName, mockConfig);
    // exception.expect(IllegalArgumentException.class);
}

Using the @rule's exception object, If I use the commented line to catch my exception, the exception created in the doThrow() construct will be lost and I cannot catch it. My unit test will fail and complain that:

Expected test to throw an instance of java.lang.IllegalArgumentException

The test works fine if I the line is commented as I have it. Here is how my method looks like that I am trying to test:

public void createTable(final String tableName, final Configuration config) throws IOException 

The method needs to throw IOException since the specific exception thrown during table creation is a subclass of IOException.

Is my catching of exception in the JUnit test wrong for this type of checking exception.

You seem to want to test whether that method throws an exception; but by using doThrow().when(sut).createTable(...) you prevent the SUT from having its normal behaviour.

Just do:

final PersonTable table = new PersonTable();
table.createTable(null, null); // theoretically throws IllegalArgumentException

And just check that there is a thrown exception. No idea how you do that with your @Rule but I don't use that and here how I'd do that:

final PersonTable table = new PersonTable();
try {
    table.createTable(null, null);
    fail("No exception thrown!");
} catch (IllegalArgumentException e) {
    assertEquals(e.getMessage(), "the expected message");
}

Your issue is that your test doesn't actually call createTable , and therefore there's nothing to throw the exception. You could write this.

@Test
public void testCreateTableWithNullTableName_throwsIOEXception() throws IOException {
    final String tableName = null;
    mockConfig = mock(Configuration.class);
    spyPersonTable = spy(new PersonTable());
    doThrow(new IllegalArgumentException()).when(spyPersonTable).createTable(tableName, mockConfig);
    exception.expect(IllegalArgumentException.class);
    spyPersonTable.createTable(tableName, mockConfig);
}

But I don't really see the point of doing that, because you'd really just be testing Mockito. You're stubbing the method so that it does nothing other than throwing IllegalArgumentException , then checking that your stubbing worked OK - which seems pointless to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM