2013-03-08 98 views
8

我似乎无法弄清楚为什么我的一个测试失败。JUnit测试失败,虽然预期的异常抛出

这里的测试:

@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)); 
} 

我设置一个断点,并通过流程多次了。它进入ChessPiece类中的第二个if语句,似乎抛出异常。该过程然后返回到Rook类,并在super块下返回false。

关于发生了什么的任何想法?由于

相关代码:

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(); 
    } 
} 
+1

很难理解你刚才给出的部分代码是怎么回事。你能把它简化成一个简短但完整的例子吗?如果你期望'isValidMove'引发异常,为什么你还会*有一个断言(你不会到达)? – 2013-03-08 06:56:46

+2

哦,你的'ChessPiece.isValidMove'实现是无效的代码 - 它不会返回任何东西。这表明你没有运行你发布的代码。 – 2013-03-08 06:58:06

+0

testfailure说什么? – 2013-03-08 06:58:43

回答

3

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.

正在发生的事情是在isValidMove()Rook的类中的第一行调用super方法,以便控制去那里,但由于第二if的条件没有得到满足它抛出IllegalArgumentException,然后控制返回到子类,即Rook,它不能现在return false因为super已抛出异常,所以异常将从此方法外抛出,并将从juni重新抛出t complainsIfFromLocIsDifferentObject方法。

这将被JUnit框架所理解并且应该通过测试用例。

检查测试用例类是否有这一行@RunWith(value = BlockJUnit4ClassRunner.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(); 
    } 
} 

这个测试用例通过我。

+0

我没有在测试用例类中的@RunWith(BlockJUnit4ClassRunner.class)当我添加它时,我得到一个错误,值是未定义注释类型RunWith” 什么是试图做啊? – JZachow 2013-03-08 07:42:02

+1

'@RunWith(值= BlockJUnit4ClassRunner.class)'用这个代替 – 2013-03-08 07:43:08

+0

该代码的工作,但测试仍然失败。 – JZachow 2013-03-08 07:46:45

1

正如您在评论的JUnit写的告诉你什么是错的:

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

您从一个断言得到一个AssertionError,可能预期的异常被抛出之前,或者因为异常被处理,然后断言执行失败了。

如果从注释中删除“预期”值的JUnit会给你在哪里断言失败的确切位置(又名堆栈跟踪)

0

平常我不把周围的代码JUnit断言,我期待例外扔。

所以

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

否则的例外是包装在一个assertionException异常的JUnit的断言语句中抛出。