LINQ `Any` not covered by unit test

Viewed 339

I've got this method:

/// <summary>
/// Moves piece to location, does not verify that this is a valid move
/// </summary>
/// <param name="dest"></param>
public virtual void Move(Coordinate dest)
{
    if (Board.IsPieceAtLocation(dest))
    {
        if (GetAllPossibleKills().Any(p => p.BoardLocation == dest))
        {
            Board.KillPieceAtLocation(dest);
        }
        else
        {
            throw new LocationOccupiedException("Board location already occupied and kill is not valid",this, Board.GetPieceAtLocation(dest));
        }
    }
    BoardLocation = dest;
}

And it's covered by two unit tests:

[Test]
public void LocationOccupiedTest()
{
    Board board = new Board();
    board.GenerateNewGamePieces();
    Assert.Throws<LocationOccupiedException>(()=>board.GetKing(false).Move(new Coordinate(0,0)));
}

[Test]
public void KillPieceTest()
{
    Board board = new Board();
    board.GenerateNewGamePieces();
    Piece knight = board.GetPieceAtLocation(new Coordinate(1, 0));
    knight.Move(new Coordinate(1,4));
    Assert.DoesNotThrow(()=>knight.Move(new Coordinate(0,6)));
}

According to the coverage analysis, the whole method is covered except for:

if (GetAllPossibleKills().Any(p => p.BoardLocation == dest))

You can see the coverage status next to each line of code:

Coverage Screenshot

I don't understand how that can be the case given both branches of the if statement are traversed.

How can I get this covered?

1 Answers

I suspect the issue is that you are not testing all possible execution paths for the Any.

You may need to add extra test cases to ensure you cover (for example) moving illegally when there are other valid targets (thanks for the example @Persistence).


To fix this specific example, you'd need to add a test case for moving to an occupied space that isn't a valid kill target when there are other valid kill targets.

[Test]
public void MoveToOccupiedWithOtherValidTargets()
{
    Board board = new Board();
    board.GenerateNewGamePieces();
    Piece king = board.GetKing(true);
    king.Move(new Coordinate(0,5));
    board.GetPieceAtLocation(new Coordinate(0,1)).Move(new Coordinate(0,4));
    Assert.Throws<LocationOccupiedException>(()=>king.Move(new Coordinate(0,4)));
}
Related