2015-11-29 96 views
-1

我试图测试下面代码的updateGame方法的返回值。依赖方法的Junit测试

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

} 

我的JUnit测试代码如下

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

} 

当我在Eclipse中运行JUnit测试的情况下,我没有得到任何结果。有人能帮我解决问题吗?

enter image description here

感谢

回答

0

我认为你有一个无限循环。 当你调用startGame方法,你这样做:

while(true) { // Your Code... } 

你必须想办法完成这个循环在您的测试。

@After只在测试完成时调用。