web-dev-qa-db-fra.com

Le test JUnit échoue bien qu'une exception attendue soit levée

Je n'arrive pas à comprendre pourquoi l'un de mes tests échoue.

Voici le 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));
}

J'ai défini un point d'arrêt et suivi le processus plusieurs fois. Il entre dans la deuxième instruction if de la classe ChessPiece et semble lancer l'exception. Le processus retourne ensuite à la classe Rook et renvoie false sous le bloc super.

Des idées sur ce qui se passe? Merci

Code pertinent:

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

Il entre dans la deuxième instruction if de la classe ChessPiece et Semble lancer l'exception. Le processus retourne ensuite à la classe Rook Et renvoie false sous le super bloc.

Ce qui se passe est la première ligne de la méthode isValidMove() de Rook appelle super et le contrôle y passe, mais comme la condition de second if n'est pas remplie, elle renvoie IllegalArgumentException puis le contrôle retourne à la classe enfant ie Rook et il ne peut pas return false maintenant. comme super a lancé une exception, l’exception sera rejetée en dehors de cette méthode et sera rejetée à partir de la méthode junit complainsIfFromLocIsDifferentObject.

Ceci sera compris par le framework JUnit et devrait réussir le scénario de test.

Vérifiez si vous avez cette ligne @RunWith(value = BlockJUnit4ClassRunner.class) dans la classe de cas de test.

METTRE À JOUR:

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

Ce cas de test passe pour moi.

4
Narendra Pathai

Lorsque vous écrivez dans un commentaire, JUnit vous dit ce qui ne va pas:

J'obtiens "Java.lang.AssertionError: Exception attendue: Java.lang.IllegalArgumentException 

Vous obtenez une erreur AssertionError, probablement d'une assertion avant la levée de l'exception attendue ou parce que l'exception est gérée, puis une assertion qui échoue.

Si vous supprimez la valeur "attendue" de l'annotation, JUnit vous indiquera l'emplacement exact où l'assertion a échoué (a.k.a. stacktrace)

3
Jens Schauder

Habituellement, je ne mettrais pas d'assertions JUnit autour du code que l'exception est censée générer.

Alors

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

Sinon, l'exception est levée dans l'instruction assert JUnit qui englobe l'exception dans une assertionException.

0
Simon Hellinger