JZachow
JZachow

Reputation: 187

JUnit test failing although expected exception is thrown

I can't seem to figure out why one of my tests is failing.

Here's the test:

@Test(expected = IllegalArgumentException.class)
public void complainsIfFromLocIsDifferentObject() throws Throwable {
    board.set(make(), 1, 3); //Creates different rook from 'piece'
    assertFalse("ChessPiece Test 2", piece.isValidMove(getValidMove(1, 3), board));
}

I've set a breakpoint and gone through the process multiple times. It goes into the second if-statement in the ChessPiece class, and seems to throw the exception. The process then goes back to the Rook class and returns false under the super block.

Any ideas as to what's happening? Thanks

Relevant code:

public class Rook extends ChessPiece {

    @Override
    public boolean isValidMove(Move m, IChessBoard b) {
        if (super.isValidMove(m, b) == false)
            return false;

        // Add logic specific to rook
        if(m.fromRow == m.toRow || m.fromColumn == m.toColumn)
            return true;
        else 
            return false;
    }
}


public abstract class ChessPiece implements IChessPiece {

    @Override
    public boolean isValidMove(Move m, IChessBoard b) {

        //Verify that there is a piece at the origin
        if (b.pieceAt(m.fromRow,m.fromColumn) == null)
            throw new IllegalArgumentException();

        // Verify that this piece is located at move origin
        IChessPiece piece = b.pieceAt(m.fromRow, m.fromColumn);
        if (this != piece)
            throw new IllegalArgumentException();
     }
}

Upvotes: 16

Views: 103639

Answers (3)

Simon Hellinger
Simon Hellinger

Reputation: 1329

Usually I'd not put JUnit assertions around code that I expect the exception to throw.

So

@Test(expected = IllegalArgumentException)
public void test() {
   board.set(make(), 1, 3); //Creates different rook from 'piece'
   piece.isValidMove(getValidMove(1, 3), board);
}

Otherwise the exception is thrown within the JUnit assert statement which wraps the exception in an assertionException.

Upvotes: -1

Jens Schauder
Jens Schauder

Reputation: 81862

As you write in a comment JUnit tells you what is wrong:

I get "java.lang.AssertionError:Expected exception: java.lang.IllegalArgumentException

You get an AssertionError, probably from an assertion before the expected exception gets thrown or because the Exception gets handled and then an assertion executed which fails.

If you remove the 'expected' value from the annotation JUnit will give you the exact location where the assertion failed (a.k.a. stacktrace)

Upvotes: 8

Narendra Pathai
Narendra Pathai

Reputation: 41935

It goes into the second if-statement in the ChessPiece class, and seems to throw the exception. The process then goes back to the Rook class and returns false under the super block.

What is happening is the first line in the isValidMove() of Rook class calls super method so control goes there, but due to the condition of second if not being met it throws IllegalArgumentException and then control returns back to child class ie Rook and it cannot return false now as super has thrown an exception so the exception will be re thrown outside from this method and will be re-thrown from junit complainsIfFromLocIsDifferentObject method.

This will be understood by JUnit framework and should pass the test case.

Check if you have this line @RunWith(value = BlockJUnit4ClassRunner.class) at the test case class.

UPDATE:

@RunWith(value = BlockJUnit4ClassRunner.class)
public class Test extends TestCase{

    @Test(expected = IllegalArgumentException.class)
    public void test1() throws Throwable{
        assertFalse(throwException());
    }

    private boolean throwException(){
        throw new IllegalArgumentException();
    }
}

This test case passes for me.

Upvotes: 10

Related Questions