diff --git a/app/build.gradle b/app/build.gradle
index b8c6a0de5bbc94f632fa75a450bd3c14665f2ca6..81ee478a283b79fcd552956eb94d4ff12a064b46 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -23,6 +23,9 @@ dependencies {
     // This dependency is used by the application.
     implementation 'com.google.guava:guava:30.1.1-jre'
     implementation 'mysql:mysql-connector-java:8.0.28'
+// Mockito
+    testImplementation 'org.mockito:mockito-core:3.10.0'
+
 }
 
 application {
diff --git a/app/src/main/java/brickbreaker/Ball.java b/app/src/main/java/brickbreaker/Ball.java
index ca11a7d6cf4cd65cd39855206041d280693e846e..dfe27b4f3c759bd0c21bd8cd0604434c9644d6b1 100644
--- a/app/src/main/java/brickbreaker/Ball.java
+++ b/app/src/main/java/brickbreaker/Ball.java
@@ -28,6 +28,14 @@ public class Ball {
         return this.position;
     }
     
+    public int getRadius() {
+        return this.radius;
+    }
+    
+    public Color getColor() {
+        return this.color;
+    }
+    
     public Vector getDirection() {
         return this.direction;
     }
diff --git a/app/src/main/java/brickbreaker/DefaultGameRenderer.java b/app/src/main/java/brickbreaker/DefaultGameRenderer.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8d30a2dc6c95dc627d8ab3313df83d250faae0a
--- /dev/null
+++ b/app/src/main/java/brickbreaker/DefaultGameRenderer.java
@@ -0,0 +1,80 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package brickbreaker;
+
+import brickbreaker.Interfaces.GameRenderer;
+import java.awt.*;
+import java.util.Iterator;
+import java.util.List;
+import javax.swing.JPanel;
+
+public class DefaultGameRenderer implements GameRenderer {
+    @Override
+    public void render(
+        GamePanel gamePanel,
+        Graphics graphics,
+        List<Ball> balls,
+        int paddle,
+        ScoringSystem scoringSystem,
+        int totalBricks
+    ) {
+        if (balls.isEmpty()) {
+            gamePanel.gameOver(graphics, "Game Over", Color.BLACK);
+            return;
+        }
+
+        if (!gamePanel.play) {
+            graphics.setFont(new Font(gamePanel.font, Font.BOLD, 20));
+            graphics.drawString("Press Enter to Start", 230, 350);
+            return;
+        }
+        
+        // Background color
+        graphics.setColor(Color.green);
+        graphics.fillRect(1, 1, 692, 592);
+
+        // Render game map
+        gamePanel.gameMap.draw((Graphics2D) graphics);
+
+        // Render paddle
+        graphics.setColor(Color.blue);
+        graphics.fillRect(paddle, 550, 100, 20);
+
+        Iterator<Ball> ballsIterator = balls.iterator();
+
+        while (ballsIterator.hasNext()) {
+            Ball ball = ballsIterator.next();
+            Vector ballPosition = ball.getPosition();
+
+            if (ballPosition.y > 560) {
+                ballsIterator.remove();
+                continue;
+            } else {
+                ball.checkForWallCollisions();
+            }
+
+            ball.draw(graphics);
+        }
+
+        // Render score
+        graphics.setColor(Color.black);
+        graphics.setFont(new Font("MV Boli", Font.BOLD, 25));
+        graphics.drawString("Score: " + scoringSystem.getScore(), 520, 30);
+
+        // Render high score
+        graphics.setColor(Color.black);
+        graphics.setFont(new Font("MV Boli", Font.BOLD, 25));
+        graphics.drawString("High Score: " + scoringSystem.getHighScore(), 10, 30);
+
+        if (totalBricks <= 0) {
+            Color color = new Color(0XFF6464);
+            gamePanel.gameOver(graphics, "You Won", color);
+        }
+
+        if (balls.isEmpty()) {
+            gamePanel.gameOver(graphics, "Game Over", Color.BLACK);
+        }
+    }
+}
diff --git a/app/src/main/java/brickbreaker/GamePanel.java b/app/src/main/java/brickbreaker/GamePanel.java
index c8f282de9022241dfb9df69e69a119cb9730544b..ddb6017b7d22833eec0b62e711b874ffde3f8b20 100644
--- a/app/src/main/java/brickbreaker/GamePanel.java
+++ b/app/src/main/java/brickbreaker/GamePanel.java
@@ -3,6 +3,7 @@ package brickbreaker;
 import brickbreaker.GameComponents.Brick;
 import brickbreaker.Interfaces.BrickFactory;
 import brickbreaker.GameComponents.DefaultBrickFactory;
+import brickbreaker.Interfaces.GameRenderer;
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
@@ -13,23 +14,24 @@ import java.util.Iterator;
 import java.util.List;
 
 public class GamePanel extends JPanel implements ActionListener {
-    private boolean play = false;
-    private boolean gameOver = false;
-    private ScoringSystem scoringSystem;
+    public boolean play = false;
+    public boolean gameOver = false;
+    public ScoringSystem scoringSystem;
 
-    private int totalBricks;
-    private int rows = 10;
-    private int columns = 14;
+    public int totalBricks;
+    public int rows = 10;
+    public int columns = 14;
 
-    private Timer timer;
-    private int delay = 8;
+    public Timer timer;
+    public int delay = 8;
 
-    private int paddle = 310;
+    public int paddle = 310;
 
-    private List<Ball> balls = new ArrayList<>();
-    private String font = "MV Boli";
-    private JFrame frame;
-    private GameMapBuilder gameMap;
+    public List<Ball> balls = new ArrayList<>();
+    public String font = "MV Boli";
+    public JFrame frame;
+    public GameMapBuilder gameMap;
+    private final GameRenderer gameRenderer;
 
     public GamePanel(JFrame frame) {
         Color color = Color.decode("#8B4513");
@@ -45,8 +47,46 @@ public class GamePanel extends JPanel implements ActionListener {
         addKeyBindings();
         
         scoringSystem = App.scoreSystem;
+        gameRenderer = new DefaultGameRenderer();
+    }
+    
+    public GamePanel(JFrame frame, GameRenderer gameRenderer) {
+        Color color = Color.decode("#8B4513");
+        this.balls.add(new Ball(350, 450, 2, -2, 20, color));
+        this.totalBricks = rows * columns;
+        this.frame = frame;
+        BrickFactory brickfactory = new DefaultBrickFactory();
+        gameMap = new GameMapBuilder(rows, columns, brickfactory);
+        setFocusable(true);
+        setFocusTraversalKeysEnabled(false);
+        timer = new Timer(delay, this);
+        timer.start();
+        addKeyBindings();
+        
+        scoringSystem = App.scoreSystem;
+        this.gameRenderer = gameRenderer;
+    }
+
+    
+    public List<Ball> getBalls() {
+        return balls;
+    }
+
+    // Getter for paddle
+    public int getPaddle() {
+        return paddle;
+    }
+
+    // Getter for scoringSystem
+    public ScoringSystem getScoringSystem() {
+        return scoringSystem;
     }
 
+    // Getter for totalBricks
+    public int getTotalBricks() {
+        return totalBricks;
+    }
+    
     private void addKeyBindings() {
         InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
         ActionMap actionMap = getActionMap();
@@ -110,63 +150,15 @@ public class GamePanel extends JPanel implements ActionListener {
         });
     }
     
+    @Override
     protected void paintComponent(Graphics graphics) {
         super.paintComponent(graphics);
-        if (balls.isEmpty()) {
-            gameOver(graphics, "Game Over", Color.BLACK);
-            return;
-        }
-        
-        if(!play) {
-            graphics.setFont(new Font(font, Font.BOLD, 20));
-            graphics.drawString("Press Enter to Start", 230, 350);
-            return;
-        }
-        // background color
-        graphics.setColor(Color.green);
-        graphics.fillRect(1, 1, 692, 592);
-
-        gameMap.draw((Graphics2D) graphics);
-
-
-        graphics.setColor(Color.blue);
-        graphics.fillRect(paddle, 550, 100, 20);
-
-        Iterator<Ball> ballsIterator = balls.iterator();
-
-        while (ballsIterator.hasNext()) {
-            Ball ball = ballsIterator.next();
-            Vector ballPosition = ball.getPosition();
 
-            if (ballPosition.y > 560) {
-                ballsIterator.remove();
-                continue;
-            } else {
-                ball.checkForWallCollisions();
-            }
-
-            ball.draw(graphics);
-        }
-
-        graphics.setColor(Color.black);
-        graphics.setFont(new Font("MV Boli", Font.BOLD, 25));
-        graphics.drawString("Score: " + scoringSystem.getScore(), 520, 30);
-
-        // Display the high score
-        graphics.setColor(Color.black);
-        graphics.setFont(new Font("MV Boli", Font.BOLD, 25));
-        graphics.drawString("High Score: " + scoringSystem.getHighScore(), 10, 30);
-        if (totalBricks <= 0) {
-            Color color = new Color(0XFF6464);
-            gameOver(graphics, "You Won", color);
+        if (gameRenderer != null) {
+            gameRenderer.render(this, graphics, balls, paddle, scoringSystem, totalBricks);
         }
-        
-        if (balls.isEmpty()) {
-            gameOver(graphics, "Game Over", Color.BLACK);
-        }
-
     }
-
+    
     public void gameOver(Graphics graphics, String gameOverText, Color color) {
         gameOver = true; // Set the game over flag to true
         graphics.setColor(color);
diff --git a/app/src/main/java/brickbreaker/Interfaces/GameRenderer.java b/app/src/main/java/brickbreaker/Interfaces/GameRenderer.java
new file mode 100644
index 0000000000000000000000000000000000000000..54ebc42cef4cc6fe535293e56656457b093b6161
--- /dev/null
+++ b/app/src/main/java/brickbreaker/Interfaces/GameRenderer.java
@@ -0,0 +1,19 @@
+
+package brickbreaker.Interfaces;
+
+import brickbreaker.Ball;
+import brickbreaker.GamePanel;
+import brickbreaker.ScoringSystem;
+import java.awt.Graphics;
+import java.util.List;
+
+public interface GameRenderer {
+    void render(
+        GamePanel gamePanel,
+        Graphics graphics,
+        List<Ball> balls,
+        int paddle,
+        ScoringSystem scoringSystem,
+        int totalBricks
+    );
+}
\ No newline at end of file
diff --git a/app/src/test/java/brickbreaker/AppTest.java b/app/src/test/java/brickbreaker/AppTest.java
index e86eb8d152cff5fb5a1cc30ce34cef78817077ce..338146107391f42624ca06b6c5b2592f18fc297c 100644
--- a/app/src/test/java/brickbreaker/AppTest.java
+++ b/app/src/test/java/brickbreaker/AppTest.java
@@ -3,12 +3,28 @@
  */
 package brickbreaker;
 
+import javax.swing.JFrame;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.BeforeEach;
 
 class AppTest {
-    @Test void appHasAGreeting() {
-        App classUnderTest = new App();
-        assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
+    private JFrame testFrame;
+
+    @BeforeEach
+    public void setUp() {
+        // Create a new JFrame for testing
+        testFrame = new JFrame();
+        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        testFrame.setVisible(false); // Set to invisible for testing
+    }
+
+    @Test
+    public void testCreateGame() {
+        App.frame = testFrame;
+
+        App.createGame();
+
+        assertNotNull(App.gamePanel);
     }
 }
diff --git a/app/src/test/java/brickbreaker/GamePanelTest.java b/app/src/test/java/brickbreaker/GamePanelTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b349247b7f4fb6a5455d64142304b6ba43d5385
--- /dev/null
+++ b/app/src/test/java/brickbreaker/GamePanelTest.java
@@ -0,0 +1,103 @@
+package brickbreaker;
+
+import brickbreaker.GameComponents.Brick;
+import brickbreaker.GameComponents.DefaultBrickFactory;
+import brickbreaker.Interfaces.GameRenderer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+public class GamePanelTest {
+
+    @Mock
+    private JFrame frame;
+
+    @Mock
+    private ScoringSystem scoringSystem;
+
+    @Mock
+    private GameRenderer gameRenderer;
+
+    private GamePanel gamePanel;
+
+    @BeforeEach
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        gamePanel = new GamePanel(frame, gameRenderer);
+        gamePanel.scoringSystem = scoringSystem;
+    }
+
+    @Test
+    public void testInitialization() {
+        assertEquals(1, gamePanel.getBalls().size());
+        assertFalse(gamePanel.play);
+        assertFalse(gamePanel.gameOver);
+        assertNotNull(gamePanel.timer);
+    }
+
+    @Test
+    public void testMoveRight() {
+        gamePanel.moveRight();
+        assertTrue(gamePanel.play);
+    }
+
+    @Test
+    public void testMoveLeft() {
+        gamePanel.moveLeft();
+        assertTrue(gamePanel.play);
+    }
+
+    @Test
+    public void testActionPerformed() {
+        Ball mockBall = mock(Ball.class);
+        when(mockBall.getRadius()).thenReturn(20);
+        when(mockBall.getPosition()).thenReturn(new Vector(100, 100));
+        when(mockBall.getColor()).thenReturn(Color.decode("#8B4513"));
+        when(mockBall.getDirection()).thenReturn(new Vector(-1, 1));
+        
+        List<Ball> balls = new ArrayList<>();
+        balls.add(mockBall);
+        gamePanel.balls = balls;
+         gamePanel.play = true;
+        // Create a mock Brick
+        Brick mockBrick = mock(Brick.class);
+        when(mockBrick.getIsHit()).thenReturn(false);
+        when(mockBrick.getPosition()).thenReturn(new Vector(100, 100));
+        when(mockBrick.getWidth()).thenReturn(50);
+        when(mockBrick.getHeight()).thenReturn(20);
+
+        // Create a mock GameMapBuilder and set the map to contain the mock brick
+        Brick[][] mockMap = new Brick[][]{{mockBrick}};
+        gamePanel.gameMap = new GameMapBuilder(1, 1, new DefaultBrickFactory());
+        gamePanel.gameMap.map = mockMap;
+
+        // Create a mock ActionEvent
+        ActionEvent mockActionEvent = mock(ActionEvent.class);
+
+        // Call actionPerformed method with the mock ActionEvent
+        gamePanel.actionPerformed(mockActionEvent);
+
+        // Verify that expected interactions with mocks occurred
+
+        // Verify that getPosition and getDirection are called on mockBall
+        verify(mockBall, atLeast(1)).getPosition();
+        verify(mockBall, atLeast(1)).move();
+
+        // Verify that getIsHit, getPosition, getWidth, and getHeight are called on mockBrick
+        verify(mockBrick, atLeast(1)).getIsHit();
+        verify(mockBrick, atLeast(1)).getPosition();
+        verify(mockBrick, atLeast(1)).getWidth();
+        verify(mockBrick, atLeast(1)).getHeight();
+
+    }
+    
+}
\ No newline at end of file