简体   繁体   English

虽然引发了预期的异常,但JUnit测试失败

[英]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. 它进入了ChessPiece类中的第二个if语句,似乎抛出异常。 The process then goes back to the Rook class and returns false under the super block. 然后该过程返回到Rook类并在super块下返回false。

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

It goes into the second if-statement in the ChessPiece class, and seems to throw the exception. 它进入了ChessPiece类中的第二个if语句,似乎抛出异常。 The process then goes back to the Rook class and returns false under the super block. 然后该过程返回到Rook类并在超级块下返回false。

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. 发生了什么是在Rook类的isValidMove()中的第一行调用super方法,所以控制去那里,但是由于第二个条件if没有被满足它抛出IllegalArgumentException然后控制返回到子类即Rook它不能现在return false因为super已抛出异常,因此异常将从此方法重新抛出,并将从junit complainsIfFromLocIsDifferentObject方法重新抛出。

This will be understood by JUnit framework and should pass the test case. 这将由JUnit框架理解,并应通过测试用例。

Check if you have this line @RunWith(value = BlockJUnit4ClassRunner.class) at the test case class. 检查测试用例类中是否有此行@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();
    }
}

This test case passes for me. 这个测试用例传递给我。

As you write in a comment JUnit tells you what is wrong: 当您在评论中写下JUnit时会告诉您错误:

I get "java.lang.AssertionError:Expected exception: java.lang.IllegalArgumentException 我得到“java.lang.AssertionError:预期的异常: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. 你得到一个AssertionError,可能是在抛出预期的异常之前的一个断言,或者是因为处理了Exception,然后执行了一个失败的断言。

If you remove the 'expected' value from the annotation JUnit will give you the exact location where the assertion failed (aka stacktrace) 如果从注释中删除'expected'值,JUnit将为您提供断言失败的确切位置(也称为stacktrace)

Usually I'd not put JUnit assertions around code that I expect the exception to throw. 通常我不会将JUnit断言放在我希望抛出异常的代码周围。

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. 否则,在JUnit assert语句中抛出异常,该语句将异常包装在assertionException中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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