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();
}
}
When using JUnit 4, we can simply use the expected attribute of the @Test annotation to declare that we expect an exception to be thrown anywhere in the annotated test method. In this example, we've declared that we're expecting our test code to result in a NullPointerException.
In order to handle the assertion error, we need to declare the assertion statement in the try block and catch the assertion error in the catch block.
The JUnit TestRunners will catch the thrown Exception regardless so you don't have to worry about your entire test suite bailing out if an Exception is thrown. This is the best answer.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With