dimanche 29 novembre 2015

Junit test on dependent method

I am trying to test the return value of updateGame method of below code.

package org.psnbtech;

import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

import javax.swing.JFrame;

/**
 * The {@code Tetris} class is responsible for handling much of the game logic and
 * reading user input.
 * @author Brendan Jones
 *
 */
public class Tetris extends JFrame {

    /**
     * The Serial Version UID.
     */
    private static final long serialVersionUID = -4722429764792514382L;

    /**
     * The number of milliseconds per frame.
     */
    private static final long FRAME_TIME = 1000L / 50L;

    /**
     * The number of pieces that exist.
     */
    private static final int TYPE_COUNT = TileType.values().length;

    /**
     * The BoardPanel instance.
     */
    private BoardPanel board;

    /**
     * The SidePanel instance.
     */
    private SidePanel side;

    /**
     * Whether or not the game is paused.
     */
    private boolean isPaused;

    /**
     * Whether or not we've played a game yet. This is set to true
     * initially and then set to false when the game starts.
     */
    private boolean isNewGame;

    /**
     * Whether or not the game is over.
     */
    private boolean isGameOver;

    /**
     * The current level we're on.
     */
    private int level;

    /**
     * The current score.
     */
    private int score;

    /**
     * The random number generator. This is used to
     * spit out pieces randomly.
     */
    private Random random;

    /**
     * The clock that handles the update logic.
     */
    private Clock logicTimer;

    /**
     * The current type of tile.
     */
    private TileType currentType;

    /**
     * The next type of tile.
     */
    private TileType nextType;

    /**
     * The current column of our tile.
     */
    private int currentCol;

    /**
     * The current row of our tile.
     */
    private int currentRow;

    /**
     * The current rotation of our tile.
     */
    private int currentRotation;

    /**
     * Ensures that a certain amount of time passes after a piece is
     * spawned before we can drop it.
     */
    private int dropCooldown;

    /**
     * The speed of the game.
     */
    private float gameSpeed;

    /**
     * Creates a new Tetris instance. Sets up the window's properties,
     * and adds a controller listener.
     */
    public Tetris() {
        /*
         * Set the basic properties of the window.
         */
        super("Tetris");
        setLayout(new BorderLayout());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);

        /*
         * Initialize the BoardPanel and SidePanel instances.
         */
        this.board = new BoardPanel(this);
        this.side = new SidePanel(this);

        /*
         * Add the BoardPanel and SidePanel instances to the window.
         */
        add(board, BorderLayout.CENTER);
        add(side, BorderLayout.EAST);

        /*
         * Adds a custom anonymous KeyListener to the frame.
         */
        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {

                switch(e.getKeyCode()) {

                /*
                 * Drop - When pressed, we check to see that the game is not
                 * paused and that there is no drop cooldown, then set the
                 * logic timer to run at a speed of 25 cycles per second.
                 */
                case KeyEvent.VK_S:
                    if(!isPaused && dropCooldown == 0) {
                        logicTimer.setCyclesPerSecond(25.0f);
                    }
                    break;

                /*
                 * Move Left - When pressed, we check to see that the game is
                 * not paused and that the position to the left of the current
                 * position is valid. If so, we decrement the current column by 1.
                 */
                case KeyEvent.VK_A:
                    if(!isPaused && board.isValidAndEmpty(currentType, currentCol - 1, currentRow, currentRotation)) {
                        currentCol--;
                    }
                    break;

                /*
                 * Move Right - When pressed, we check to see that the game is
                 * not paused and that the position to the right of the current
                 * position is valid. If so, we increment the current column by 1.
                 */
                case KeyEvent.VK_D:
                    if(!isPaused && board.isValidAndEmpty(currentType, currentCol + 1, currentRow, currentRotation)) {
                        currentCol++;
                    }
                    break;

                /*
                 * Rotate Anticlockwise - When pressed, check to see that the game is not paused
                 * and then attempt to rotate the piece anticlockwise. Because of the size and
                 * complexity of the rotation code, as well as it's similarity to clockwise
                 * rotation, the code for rotating the piece is handled in another method.
                 */
                case KeyEvent.VK_Q:
                    if(!isPaused) {
                        rotatePiece((currentRotation == 0) ? 3 : currentRotation - 1);
                    }
                    break;

                /*
                 * Rotate Clockwise - When pressed, check to see that the game is not paused
                 * and then attempt to rotate the piece clockwise. Because of the size and
                 * complexity of the rotation code, as well as it's similarity to anticlockwise
                 * rotation, the code for rotating the piece is handled in another method.
                 */
                case KeyEvent.VK_E:
                    if(!isPaused) {
                        rotatePiece((currentRotation == 3) ? 0 : currentRotation + 1);
                    }
                    break;

                /*
                 * Pause Game - When pressed, check to see that we're currently playing a game.
                 * If so, toggle the pause variable and update the logic timer to reflect this
                 * change, otherwise the game will execute a huge number of updates and essentially
                 * cause an instant game over when we unpause if we stay paused for more than a
                 * minute or so.
                 */
                case KeyEvent.VK_P:
                    if(!isGameOver && !isNewGame) {
                        isPaused = !isPaused;
                        logicTimer.setPaused(isPaused);
                    }
                    break;

                /*
                 * Start Game - When pressed, check to see that we're in either a game over or new
                 * game state. If so, reset the game.
                 */
                case KeyEvent.VK_ENTER:
//                  if(isGameOver || isNewGame) {
                    if(isNewGame) {
                        resetGame();
                    }
                    if(isGameOver){
                        System.exit(0);
                    }
                    break;

                }
            }

            @Override
            public void keyReleased(KeyEvent e) {

                switch(e.getKeyCode()) {

                /*
                 * Drop - When released, we set the speed of the logic timer
                 * back to whatever the current game speed is and clear out
                 * any cycles that might still be elapsed.
                 */
                case KeyEvent.VK_S:
                    logicTimer.setCyclesPerSecond(gameSpeed);
                    logicTimer.reset();
                    break;
                }

            }

        });

        /*
         * Here we resize the frame to hold the BoardPanel and SidePanel instances,
         * center the window on the screen, and show it to the user.
         */
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    /**
     * Starts the game running. Initializes everything and enters the game loop.
     */
    public void startGame() {
        /*
         * Initialize our random number generator, logic timer, and new game variables.
         */
        this.random = new Random();
        this.isNewGame = true;
        this.gameSpeed = 1.0f;

        /*
         * Setup the timer to keep the game from running before the user presses enter
         * to start it.
         */
        this.logicTimer = new Clock(gameSpeed);
        logicTimer.setPaused(true);

        while(true) {
            //Get the time that the frame started.
            long start = System.nanoTime();

            //Update the logic timer.
            logicTimer.update();

            /*
             * If a cycle has elapsed on the timer, we can update the game and
             * move our current piece down.
             */
            if(logicTimer.hasElapsedCycle()) {
                updateGame();
            }

            //Decrement the drop cool down if necessary.
            if(dropCooldown > 0) {
                dropCooldown--;
            }

            //Display the window to the user.
            renderGame();

            /*
             * Sleep to cap the framerate.
             */
            long delta = (System.nanoTime() - start) / 1000000L;
            if(delta < FRAME_TIME) {
                try {
                    Thread.sleep(FRAME_TIME - delta);
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Updates the game and handles the bulk of it's logic.
     */
    public int updateGame() {
        /*
         * Check to see if the piece's position can move down to the next row.
         */
        if(board.isValidAndEmpty(currentType, currentCol, currentRow + 1, currentRotation)) {
            //Increment the current row if it's safe to do so.
            currentRow++;
            return 0;
        } else {
            /*
             * We've either reached the bottom of the board, or landed on another piece, so
             * we need to add the piece to the board.
             */
            board.addPiece(currentType, currentCol, currentRow, currentRotation);

            /*
             * Check to see if adding the new piece resulted in any cleared lines. If so,
             * increase the player's score. (Up to 4 lines can be cleared in a single go;
             * [1 = 100pts, 2 = 200pts, 3 = 400pts, 4 = 800pts]).
             */
            int cleared = board.checkLines();
            if(cleared > 0) {
                score += 50 << cleared;
            }

            /*
             * Increase the speed slightly for the next piece and update the game's timer
             * to reflect the increase.
             */
            gameSpeed = gameSpeed + 0.035f;
            logicTimer.setCyclesPerSecond(gameSpeed);
            logicTimer.reset();

            /*
             * Set the drop cooldown so the next piece doesn't automatically come flying
             * in from the heavens immediately after this piece hits if we've not reacted
             * yet. (~0.5 second buffer).
             */
            dropCooldown = 25;

            /*
             * Update the difficulty level. This has no effect on the game, and is only
             * used in the "Level" string in the SidePanel.
             */
            level = (int)(gameSpeed * 1.70f);

            /*
             * Spawn a new piece to control.
             */
            spawnPiece();
            return cleared;
        }   
    }

    /**
     * Forces the BoardPanel and SidePanel to repaint.
     */
    private void renderGame() {
        board.repaint();
        side.repaint();
    }

    /**
     * Resets the game variables to their default values at the start
     * of a new game.
     */
    private void resetGame() {
        this.level = 1;
        this.score = 0;
        this.gameSpeed = 1.0f;
        this.nextType = TileType.values()[random.nextInt(TYPE_COUNT)];
        this.isNewGame = false;
        this.isGameOver = false;        
        board.clear();
        logicTimer.reset();
        logicTimer.setCyclesPerSecond(gameSpeed);
        spawnPiece();
    }

    /**
     * Spawns a new piece and resets our piece's variables to their default
     * values.
     */
    private void spawnPiece() {
        /*
         * Poll the last piece and reset our position and rotation to
         * their default variables, then pick the next piece to use.
         */
        this.currentType = nextType;
        this.currentCol = currentType.getSpawnColumn();
        this.currentRow = currentType.getSpawnRow();
        this.currentRotation = 0;
        this.nextType = TileType.values()[random.nextInt(TYPE_COUNT)];

        /*
         * If the spawn point is invalid, we need to pause the game and flag that we've lost
         * because it means that the pieces on the board have gotten too high.
         */
        if(!board.isValidAndEmpty(currentType, currentCol, currentRow, currentRotation)) {
            this.isGameOver = true;
            logicTimer.setPaused(true);
        }       
    }

    /**
     * Attempts to set the rotation of the current piece to newRotation.
     * @param newRotation The rotation of the new peice.
     */
    private void rotatePiece(int newRotation) {
        /*
         * Sometimes pieces will need to be moved when rotated to avoid clipping
         * out of the board (the I piece is a good example of this). Here we store
         * a temporary row and column in case we need to move the tile as well.
         */
        int newColumn = currentCol;
        int newRow = currentRow;

        /*
         * Get the insets for each of the sides. These are used to determine how
         * many empty rows or columns there are on a given side.
         */
        int left = currentType.getLeftInset(newRotation);
        int right = currentType.getRightInset(newRotation);
        int top = currentType.getTopInset(newRotation);
        int bottom = currentType.getBottomInset(newRotation);

        /*
         * If the current piece is too far to the left or right, move the piece away from the edges
         * so that the piece doesn't clip out of the map and automatically become invalid.
         */
        if(currentCol < -left) {
            newColumn -= currentCol - left;
        } else if(currentCol + currentType.getDimension() - right >= BoardPanel.COL_COUNT) {
            newColumn -= (currentCol + currentType.getDimension() - right) - BoardPanel.COL_COUNT + 1;
        }

        /*
         * If the current piece is too far to the top or bottom, move the piece away from the edges
         * so that the piece doesn't clip out of the map and automatically become invalid.
         */
        if(currentRow < -top) {
            newRow -= currentRow - top;
        } else if(currentRow + currentType.getDimension() - bottom >= BoardPanel.ROW_COUNT) {
            newRow -= (currentRow + currentType.getDimension() - bottom) - BoardPanel.ROW_COUNT + 1;
        }

        /*
         * Check to see if the new position is acceptable. If it is, update the rotation and
         * position of the piece.
         */
        if(board.isValidAndEmpty(currentType, newColumn, newRow, newRotation)) {
            currentRotation = newRotation;
            currentRow = newRow;
            currentCol = newColumn;
        }
    }

    /**
     * Checks to see whether or not the game is paused.
     * @return Whether or not the game is paused.
     */
    public boolean isPaused() {
        return isPaused;
    }

    /**
     * Checks to see whether or not the game is over.
     * @return Whether or not the game is over.
     */
    public boolean isGameOver() {
        return isGameOver;
    }

    /**
     * Checks to see whether or not we're on a new game.
     * @return Whether or not this is a new game.
     */
    public boolean isNewGame() {
        return isNewGame;
    }

    /**
     * Gets the current score.
     * @return The score.
     */
    public int getScore() {
        return score;
    }

    /**
     * Gets the current level.
     * @return The level.
     */
    public int getLevel() {
        return level;
    }

    /**
     * Gets the current type of piece we're using.
     * @return The piece type.
     */
    public TileType getPieceType() {
        return currentType;
    }

    /**
     * Gets the next type of piece we're using.
     * @return The next piece.
     */
    public TileType getNextPieceType() {
        return nextType;
    }

    /**
     * Gets the column of the current piece.
     * @return The column.
     */
    public int getPieceCol() {
        return currentCol;
    }

    /**
     * Gets the row of the current piece.
     * @return The row.
     */
    public int getPieceRow() {
        return currentRow;
    }

    /**
     * Gets the rotation of the current piece.
     * @return The rotation.
     */
    public int getPieceRotation() {
        return currentRotation;
    }

    /**
     * Entry-point of the game. Responsible for creating and starting a new
     * game instance.
     * @param args Unused.
     */
    /*public static void main(String[] args) {
        Tetris tetris = new Tetris();
        tetris.startGame();
    }*/

}

My JUnit test code is as below

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.psnbtech.Tetris;

public class TetrisTest {

    private Tetris tetris;
    @Before
    public void setUp() throws Exception {
        tetris = new Tetris();
        tetris.startGame();
    }

    @After
    public void tearDown() throws Exception {
        tetris = null;
    }

    @Test
    public void testUpdateGame() {
        int i = tetris.updateGame();
        //At any time, the no. of rows cleared should be less than or equal to 4
        assertTrue(i<=4);
    }

}

When I run JUnit test case in Eclipse, I am not getting any results. Can someone please help me where the problem is?

enter image description here

Thanks

Aucun commentaire:

Enregistrer un commentaire