I have TicTacToe game in java language and I have to do Junit test cases for this Game class, because I need to apply mutation testing for this application. can anyone help me to write good test cases.
public class Game {
private Board board;
private Queue<Player> players;
public Game() {
board = new Board();
players = new LinkedList<>();
addPlayers();
}
private void addPlayers() {
players.add(new Player("X"));
players.add(new Player("O"));
}
private void startGame() throws IOException {
do {
Player currentPlayer = players.remove();
System.out.println("Enter position for Player "+currentPlayer.toString());
java.io.BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
board.placeMarker(currentPlayer,new Position(Integer.parseInt(in.readLine()),Integer.parseInt(in.readLine())));
players.add(currentPlayer);
System.out.println(board.toString());
if(board.hasWon(currentPlayer)){
break;
}
}while (board.hasEmptyPosition());
}
public void main(String[] args) {
Game game= new Game();
try {
game.startGame();
} catch (IOException e) {
e.printStackTrace();
}
}
}
this is a very simple application, so there aren't a lot of possible tests to do.
first you should focus on testing the public API of a class, but in your case you only have main. Secondly, you depend on external input, which makes it harder to test your code...
I recommend you to read some articles on how to make your code more testable. For instance:
https://medium.com/feedzaitech/writing-testable-code-b3201d4538eb
https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters
A few starters:
Create a class responsible for starting the app (having the main method): let's call it class Application
Make Game startGame() method receive as input a function that returns the input (in your PROD code you'll use the BufferedReader, in test code you could use a stream for instance
same idea for the addPlayers method
Extract a method for each play (basically the code inside the do...while) so that you can test it as well
and maybe you can find a few more tasks
ps: but in the end, with such a basic codebase, this is kinda overkill...
Related
I (new to Java) am working on a decades old Java project built using Golden T Studios Game dev jdk. I have a game in the project which runs a 2D simulation. The code structure in a nutshell is as follows:
package game;
import java.io.*;
import java.lang.reflect.Field;
import javax.swing.JFrame;
import com.golden.gamedev.GameLoader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import sometcpimports.*;
public class MainGAME extends JFrame implements Runnable {
public static void main(String[] args) { //call new MainGAME;
}
public MainGAME() {//initiate game parameters;
//start new THREAD;
}
#Override
public void run() { //initiate new game and environment;
game = new GameLoader();
gameenv = new GameEnvironment(params); //This class is in another file "public class GameEnvironment extends Game {}"
//I don't clearly undertsand what the following lines do, so I'm mentioning them as is;
game.setup(gameenv, dimensions);
this.setVisible(false);
gameenv.setVisible(false);
game.start();
game.setVisible(true);
//tbd (code reaches this step)
}
}
My goal is to run the above simulation multiple times (with different inputs each time) and extract information after each run in a new main class as follows.
public class gamedriver {
public static void main(String[] args) {
MainGAME.params = some params;
MainGAME.main(); // runs the simulation;
//tbd1 (code doesn't reach this step)
}
}
The issue is that, on running the simulation from a different file (new main class), I am unable to exit 2D simulator after one run. The code doesn't reach //tbd1 in the new main class which has some output print statements. Essentially I want to simply exit simulator and not the whole JVM. So far I've tried:
game.stop() & gameenv.finish() at //tbd which does nothing.
System.exit(0) at //tbd which exits game after simulation but also exits jvm and doesnt reach the other main class.
finish() at both //tbd and GameEnvironment class which behaves exactly like point 2.
Additionally, I am unable to run the above (MainGAME in gamedriver class) in a for loop. This throws Game.Exception error. I understand it has something to do with threads but I'm not sure how to run them.
Thank you for your time. Appreciate your help!
I found a method to solve the above problem. I'm posting my workaround as a reference for someone who encounters a similar issue. Please note that there might be other (better) solutions out there.
I disabled all (any) threads implementation in the MainGAME (by simply commenting it out).
I added System.out.println() in MainGAME to print all my outputs at the end of simulation.
My second script uses Runtime processes to execute MainGAME:
public class gamedriver {
public static void main(String[] args) {
try {
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String path = System.getProperty("java.home") + separator + "bin" + separator + "java";
String[] command = new String[]{path, "-cp", classpath, gamedriver.GAME.class.getName(), "output.csv"};
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
static class GAME {
public static void main(String args[]) {
PrintStream out = null;
try {
out = new PrintStream(args[1]);
} catch (FileNotFoundException p) {
p.printStackTrace();
}
System.setOut(out);// this catches all output from the game to a csv file (output.csv)
MainGAME temp = new MainGame(some params); // initiate the simulation
temp.run()
out.close();
System.exit(0); // force close the simulator
}
}
}
I parse output.csv to get the solution.
This might be a sloppy way to solve the issue, but it worked for me, especially because none of the other methods provided by GTGE worked.
I am trying to learn threads in java, and got this idea of implementing a coin phone functionality using threads.
I am able to write down the basic tasks. My Flow chart is as below.
I have tried writing a class for checking hook status.
public class Hook {
static Logger log = Logger.getLogger(Hook.class.getName());
OffTheHook offTheHook= new OffTheHook();
void checkHook(Boolean hookStatus, String keyPressed){
log.debug("Hook Status "+hookStatus);
if(hookStatus==true){
offTheHook.beforeDroppingCoin(hookStatus);
}else{
if(keyPressed!=null){
DisplayMessages.displayMessage("FollowInstruction");
}else{
displayReadyMessage();
}
}
}
public static void displayReadyMessage(){
DisplayMessages.displayMessage("ready");
}
}
Another timer class..
public class TimerClass extends Thread{
int timeInMilli;
boolean status=false;
public TimerClass(int timeInMilli){
this.timeInMilli=timeInMilli;
}
#Override
public void run() {
timer();
}
private void timer(){
try {
Thread.currentThread().sleep(timeInMilli);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
How do I make these classes communicate with each other(small example will be enough). Moreover my requirement is if the headset is back on the hook the call must get cut.. How should I write the code to monitor that status? based on that status I need to make decision. At the same time I need to have another Thread that shall input status of hooks.
A small snippet of code will be that does the similar functionality, will be of great help.
Question: Ok, so this is going to sound slightly confusing due to my lack of total understanding on the subject. Currently, I am creating a game following a youtube tutorial (to understand the basics of game development in java).
After following some of the tutorials, I am confused as to what is the real purpose of the main method and the class that contains it. I thought that the main method's job was to call all the methods of its own class and the desired methods in other classes. However in my main method in my main "Game" class, here is all I have:
public static void main (String[] args) {
JFrame frame = new JFrame(title);
frame.add(game);
frame.setSize(WIDTH,HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.pack();
game.start();
}
Does frame.add(game) (game is an instance of Game) "call" all the other methods in other classes? Whatl the exactly does frame.add() do? Also, I am still trying to understand threads despite reading a lot of explanations. When I write game.start(); to "start" the thread, what exactly does this imply? Does it call all the methods in the game class only?
Here is my thread code if its needed:
private synchronized void start() {
if(running) {
return;
} else {
running = true;
}
thread = new Thread(this);
thread.start();
}
public synchronized void stop(){
if(!running) {
return;
} else {
running = false;
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit((0));
}
Here are the variables I initialized:
private static final long serialVersionUID = -8921419424614180143L;
public static final int WIDTH = 640;
public static final int HEIGHT = WIDTH / 4*3;
public static String title = "Game";
public static Game game = new Game();
public static GameState state = GameState.MENU;
private boolean running = false;
private Thread thread;
private Renderer gfx;
public static Game getInstance(){
I am just unsure of how all other methods in the game class and my other classes are being called if this is all I have in my main method. Any help would be GREATLY appreciated. I am really struggling here as you can probably tell.
The purpose of the main() method is to give an entry point for stand alone execution.
In your case (you did not show how game is initialized but I guess it was a static Game game = new Game(); initialized field) what happens is that first the static fields are initialized (which will call the Game() constructor).
Then the main method is started. It will set the initialized game as the content of the frame (which means the Frame will call various UI related methods like paint() from that moment on. Threading in Gui is a quite complicated topic, but for the sake of your question you can ignore it).
The rest of the methods in main are used to set up the containing frame. That's unusual for bigger applications but quite common for such small examples. (It does cause methods on game being called, for example for layout or drawing).
So finally main calls game.start() (which is the start() method on Game you have shown). It does create a new thread, which executes (by definition) the run() method on the Runable given to the new Thread(this) constructor (this, which is at this point the same instance as game).
The main() method is like any other method with respect to what it executes. Only what you explicitly execute (call) will be executed.
There is no method to automatically call all the other methods, because there is no purpose for such method. If, for some weird reason, you want such a method, just write it and from within it, do call the other methods.
A thread is a separate execution path in your program. When you call start() it begins and practically it goes to its special run() method, which is executed in parallel.
Any good introductory Java book should have detailed explanations to your questions.
The shortest answers that get at your bolded questions are:
frame.add(...) adds a component (like a button or label) to a frame or panel.
game.start() creates a new thread and calls the run() method of the game class in that thread.
So other methods you've written are called from game.run(). If they aren't in there (and they aren't in main(...)), they aren't being called.
I have to agree with the comment from PM77 though. It sounds like you're beginning in java, and Threading and GUIs are both pretty complex topics. There are basic games you can design (ie tic-tac-toe) that don't require either of them. Try those out before you tackle something as challenging as this.
I found really hard to write unit test for this method, it basically exits the program when user types a quit command.
SytemExit class:
public class SystemExit {
public void exit(int status) {
System.exit(status);
}
}
My static method:
public static void exitWhenQuitDetected() {
final SystemExit systemExit = new SystemExit();
final String QUIT = "quit";
String line = "";
try {
final InputStreamReader input = new InputStreamReader(System.in);
final BufferedReader in = new BufferedReader(input);
while (!(line.equals(QUIT))) {
line = in.readLine();
if (line.equals(QUIT)) {
System.out.println("You are now quiting the program");
systemExit.exit(1);
}
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
Something is not quite right here as I am struggling to unit test the method exitWhenQuitDetected (I am using Mockito for mocking). How would I mock the InputStreamReader and verify the SystemExit.exit method gets called when it sees a quit? Can you shed some lights on this please? Thanks.
Added the test I am working on at the moment, it's not working.
#Test
#Ignore
public void shouldExitProgramWhenTypeQuit() {
String quit = "quit";
SystemExit systemExit = mock(SystemExit.class);
try {
BufferedReader bufferedReader = mock(BufferedReader.class);
when(bufferedReader.readLine()).thenReturn(quit + "\n");
SomeClass.exitWhenQuitDetected();
verify(systemExit, times(1)).exit(1);
} catch (IOException e) {
e.printStackTrace();
}
}
You should include the PowerMockito Jars into your project rather than just vanilla Mockito. The Powermock library is designed for mocking Static and/or Final classes and methods.
The following this blog post contains example code describing a similar scenario to yours.
Essentially you require a test class similar to this...
#RunWith(PowerMockRunner.class)
#PrepareForTest({System.class, ClassToTest.class})
public class SystemExitTest {
#Test
public void shouldCallSystemExit() {
PowerMockito.mockStatic(System.class);
ClassToTest.methodToTest();
PowerMockito.verifyStatic();
System.exit(0);
System.out.println("If this message displays them System.exit() was mocked successfully");
}
}
Given this simple implementation class...
public class ClassToTest {
public static void methodToTest() {
// do some stuff
System.exit(0);
}
}
You've done 90% of the work already, by placing the actual exiting code off in a separate class with no logic of its own. Your difficulty is caused by your use of a static method.
I would advise making the exitWhenQuitDetected not static. Put it in a class that you can instantiate when you need it, and that you can create with a mocked SystemExit. Something like this.
public class SomeClass{
private final SystemExit exiter;
private final static String QUIT = "quit";
public SomeClass(){
this(new SystemExit());
}
SomeClass(SystemExit exiter){
this.exiter = exiter;
}
public static void exitWhenQuitDetected() {
String line = "";
try {
final InputStreamReader input = new InputStreamReader(System.in);
final BufferedReader in = new BufferedReader(input);
while (!(line.equals(QUIT))) {
line = in.readLine();
if (line.equals(QUIT)) {
System.out.println("You are now quiting the program");
exiter.exit(1);
}
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
// ...
}
Then, in your test, you can make a mock of SystemExit, and use the package-private constructor of SomeClass to create an object that will use your mock as its exiter. You can then run your test, and verify on your mock SystemExit.
There is no real way to test you SystemExit class since exercising it will cause the JVM to exit. You might be able to do something with a SecurityManager which detects and rejects the System.exit(), but that's going to be a whole lot of work to test a single line of code.
You've done the right thing - you've pulled the functionality into a small class. If I were you, I would put an interface on it and inject it via the interface into the parsing code. Then in your test you can inject a mock and test that your parsing code calls the exit() method on the mock with the right exit code.
The code in the SystemExit class is small and self-contained enough to look at and reason about without testing, IMHO.
Plenty of technical solutions were offered. I would like to point out another perspective:
This code should not really be unit tested.
The best gain you get out of unit tests is when applying them to complex business code, especially with a lot of branching.
In cases where the code is trivial, I would advise against writing unit tests around it since it simply just does not have a high enough return of investment. your case actually exacerbates my claim, think of the amount of effort it takes you to test simple code such as this and compare it with the gain.. does this really worth the effort. Does this really make you trust your own code more?
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class Boggle {
Board board;
Player player;
Timer timer;
boolean active;
static Scanner in = new Scanner(System.in);
public Boggle() {
board = new Board(4);
timer = new Timer();
}
public void newGame() {
System.out.println("Please enter your name: ");
String line = in.nextLine();
player = new Player(line);
active = true;
board.shuffle();
System.out.println(board);
timer.schedule(new timesUP(), 20000);
while(active) {
String temp = in.nextLine();
player.addGuess(temp);
}
}
public void endGame() {
active = false;
int score = Scoring.calculate(player, board);
System.out.println(score);
}
class timesUP extends TimerTask {
public void run() {
endGame();
}
}
public static void main(String[] args) {
Boggle boggle = new Boggle();
boggle.newGame();
}
}
I have the above class which should perform a loop for a given length of time and afterwards invoke an instance method. Essentially I need the loop in newGame() to run for a minute or so before endGame() is invoked on the current instance. However, using the Timer class I'm not sure how I would invoke the method I need on the current instance since I can't pass any parameters to the timertasks run method?
Is there an easy way to do this or am I going about this the wrong way? (note: this is a console project only, no GUI)
==========
code edited
I've changed the code to the above following the recommendations, and it works almost as I expect however the thread still doesnt seem to end properly. I was the while loop would die and control would eventually come back to the main method. Any ideas?
Because timesUP (please change the name!) is an inner class, it already has a reference to the instance of Boggle which created it. (That wouldn't be the case if it were marked as static.) If you wanted to create an instance of timesUP associated with another instance, you'd do something like:
otherBoggle.new timesUp();
It's pretty odd syntax, admittedly :)
This doesn't fix the problem that Midhat identified, admittedly - but it means you don't need to worry about getting a reference to the outer class. Just call endGame() from within timesUP.run() and it will call it on the appropriate instance.
You have blocking console input in the thread. The running time will be dictated by that. You can have the console input in a seperate thread, and add a timer in the current thread to kill the input thread after a minute, and call this.endGame()