I am trying to write a tester class to test a file that has already been compiled. I am basically trying to see if the coordinates of are correct when rotated 90 degrees. I am not really sure how to write a tester class. ANy advice on how to do this?
public static void testRotate90(){
int fails = SUnit.testsFailed();
System.out.println ("Testing Rotate 90...");
CartesianPoint cp = new CartesianPoint();
CartesianPoint cp2 = cp.rotate90();
if (fails == SUnit.testsFailed())
System.out.println(" PASS");
}
You should use asserts to compare what you expect the result to be to the actual result. A test fails as a result of either an invalid assertion or calling the fail() method (for instance if you expect an exception to be thrown you might put a call to fail on the line that should not be reached).
You don't have to worry about producing output for the test, the test framework will record what assertions failed for which test class.
Let's say your CartesianPoint class looks like:
public class CartesianPoint {
private final long x;
private final long y;
public CartesianPoint(long x, long y) {
this.x = x; this.y = y;
}
public CartesianPoint rotate90() {
// actual logic omitted, hardcoding result
return new CartesianPoint(0, 1);
}
public long getX() {return x;}
public long getY() {return y;}
}
Then if you expect to create a point with x = 1 and y = 0 and rotate it to get x = 0 and y = 1, the test could look like:
public class SomeTest {
public void testRotate90(){
CartesianPoint cp = new CartesianPoint(1,0);
CartesianPoint cp2 = cp.rotate90();
SUnit.assertEquals(0, cp2.getX());
SUnit.assertEquals(1, cp2.getY());
}
}
For cases like this you may want to test using a number of different inputs, see this question for an example of how to write a parameterized test using JUnit.
Related
Is there a way to create a listener (JavaFX) for any changes made to any of an object's field?
I have a coordinate object:
public class Coord {
public int x;
public int y;
public Coord(int aX, int aY) {
x = aX;
y = aY;
}
}
I have a component that creates a coordinate object when the mouse enters and destroys it when it exits. I've attached an invalidation listener:
this.setOnMouseEntered(event -> {
_hoverCoord = new SimpleObjectProperty<Coord>(getCoord(event.getX(), event.getY()));
_hoverCoord.addListener(redraw);
});
this.setOnMouseExited(event -> {
_hoverCoord = null;
});
When the mouse moves, I've been creating a new coordinate. Great, the invalidation fires because I'm replacing the coordinate. But this creates a whole bunch of these short-lived objects. I've resolved this by just calling the code I want directly in the mouse move, but it raised the following questions:
My first question is: Is that kind of rapid-fire object creation/destruction worth worrying about, generally? (I know that's a hard question to answer but I'm thinking in terms of garbage collection when creating tens of thousands of objects in a short time.)
My second question is: Is there a "listener" that just watches a POJO like Coord for field level changes?
My third question is: If not, is there a way to preserve Coord as a simple object and yet listen for specific field changes (without adding methods or changing the x and y from int)? I mean, no accessors for the fields.
My fourth question is: If not, how would I put in the accessors in Coord?
First, transform your Coord in a JavaFX Bean:
public class Coord{
private final IntegerProperty x = new SimpleIntegerProperty(this, "x");
private final IntegerProperty y = new SimpleIntegerProperty(this, "y");
public final void setX(int x){ this.x.set(x); }
public final int getX(){ return x.get(); }
public final IntegerProperty xProperty(){ return this.x; }
//Repeat for y.
}
Then, you may add an invalidation or change listener to the x property:
myCoordinate.xProperty().addListener(redraw);
myCoordinate.yProperty().addListener(redraw);
Now, there's a question: why do you need to listen the coordinates? If you need to compute something, you may use the helper Bindings, for instance, if you want to compute x*y each time the cursor moves, then you may use:
productProperty.bind(Bindings.createIntegerBinding(
()->coordinate.getX() * coordinate.getY(), //Compute x*y
coordinate.xProperty(), //dependency on x property
coordinate.yProperty()//dependency on y property
));
Or you may create your readonly property:
private final ReadOnlyIntegerWrapper product = new ReadOnlyIntegerWrapper(this, "product");
public Coord(){
init();
}
private void init(){
product.bind(Bindings.createIntegerBinding(
()->coordinate.getX() * coordinate.getY(), //Compute x*y
coordinate.xProperty(), //dependency on x property
coordinate.yProperty()//dependency on y property
));
}
public final int getProduct(){
return product.get();
}
public final ReadOnlyIntegerProperty productProperty(){
return product.getReadOnlyProperty();
}
I'm developing a game in which there're many classes. The game appears like a grid plane. I have a function which can detect whether a grid consist of any kind of specified class of object. This function return true if the grid contain any one of the specified type of object and return false if there's none.
However, when the number of classes needed to be detected increase, the parameter list can easily become awfully long, does anyone know how can I resolve that problem? Any design pattern would help? Or my design is acceptable in this case?
public boolean sameClass(int x, int y, String... className) {
for (Entity entity : entities) {
if (entity.getX() == x && entity.getY() == y) {
for (String name : className) {
if (name == entity.getClassName()) {
return true;
}
}
}
}
return false;
}
examples of using the method
sameClass(x, y - 1, "Boulder", "Enemy", "Wall")
sameClass(x, y - 1, "Player")
You can send Collection to your method:
Set<String> params = new HashSet("Boulder", "Enemy", "Wall");
boolean result = sameClass(x, y - 1, params);
You can use Builder-like pattern:
boolean result = new Checker(x, y - 1)
.param("Boulder")
.param("Enemy")
.param("Wall")
.check();
Also, if "Boulder", "Enemy", "Wall" are class of unit, it's better to use Enum instead of strings.
=== Example of possible solution ===
public class Checker {
private int x;
private int y;
private Set<Type> params = new HashSet();
// Entity related code here
public Checker(int x, int y) {
this.x = x;
this.y = y;
}
public Checker param(Type type) {
this.params.add(type);
return this;
}
public boolean check() {
for (Entity entity : entities) {
if (entity.getX() == x && entity.getY() == y) {
return params.contains(entity.getType());
}
}
return false;
}
public enum Type {
BOULDER,
ENEMY,
WALL,
PLAYER
}
}
First of all, don't ever try to compare java strings for equality using '==' unless otherwise you are testing for reference equality only. Rather use .equals() method. Read How do I compare strings in Java? to know more on this aspect.
And, for your actual problem, you can use different techniques. I would prefer to send array of Strings as parameter to keep the method call simple.
Implement your method like below:
public boolean sameClass(int x, int y, String[] className) {
for (Entity entity : entities) {
if (entity.getX() == x && entity.getY() == y) {
for (String name : className) {
if (name.equals(entity.getClassName())) {
return true;
}
}
}
}
return false;
}
Then create a class to store all the possible class name check combination you want to check for:
public class ClassNameCollection {
public static final String[] detectMultiple = new String[]{ "Boulder", "Enemy", "Wall" };
public static final String[] detectPlayer = new String[]{ "Player" };
}
When using this method, try something like below:
sameClass(x, y - 1, ClassNameCollection.detectMultiple);
sameClass(x, y - 1, ClassNameCollection.detectPlayer);
This is actually similar to the way you are handling it using var..args but one advantage of using this way I have described is, for a particular purpose (in your case- detecting wall, detecting equipable , etc.) you can create array of strings once and can call the method using that array variable multiple number of times without the need of writing those large number of lists of class names several times.
I just started taking Computer Science (Java) about 5 weeks ago and I am still having trouble creating methods. I was assigned to create an NFL statistic class and then create a method to show a calculation. Everything went smooth until I went to call my method in a test class. What seems to be missing here?
NFLPlayer CLASS (Containin the method):
private int touchdowns;
private int interceptions;
private int passingAttempts;
private int completedPasses;
private int passingYards;
private int runningYards;
private int recievingYards;
private int tackles;
private int sacks;
// Method for Quarterback rating
public double QBRating(int touchdowns, int passingAttempts, int completedPasses,
int passingYards, int interceptions) {
double a = (completedPasses / passingAttempts - 0.3) * 5;
double b = (passingYards / passingAttempts - 3) * 0.25;
double c = (touchdowns / passingAttempts) * 25;
double d = 2.375 - (interceptions / passingAttempts * 25);
double ratingQB = ((a + b + c + d) / 6) * 100;
{
return ratingQB;
}
}
Now here is my test class where I am having trouble displaying my calculations
class MyTest {
public static void main(String[] args) {
NFLPlayer playerStats = new NFLPlayer();
//Player1 finding quarterback rating
int touchdowns = 2;
int passingAttempts = 44;
int passingYards = 285;
int interceptions = 1;
int completedPasses = 35;
// Call QB rating method
playerStats.QBRating(touchdowns, passingAttempts, completedPasses,
passingYards, interceptions);
System.out.println(QBRating);
}
}
Instead of passing so many int arguments (easy to mix them up) to your method you could give your NFLPlayer class private fields for each value:
public class NFLPlayer {
private final String name;
private int touchdowns;
private int passingAttempts;
private int completedPasses;
private int passingYards;
private int interceptions;
public NFLPlayer(String name) {
this.name = name;
}
// Method names start with a lower case character in Java
// The name should usually be an imperative 'do something' not a noun ('something')
// although there are exceptions to this rule (for instance in fluent APIs)
public double calculateQbRating() {
double a = (completedPasses / passingAttempts - 0.3) * 5.0;
double b = (passingYards / passingAttempts - 3.0) * 0.25;
// an AritmeticException will occur if passingAttempts is zero
double c = (touchdowns / passingAttempts) * 25.0;
double d = 2.375 - (interceptions / passingAttempts * 25.0);
return ((a + b + c + d) / 6.0) * 100.0;
}
public String getName() {
return name;
}
// setter for the touchdowns field
public void setTouchdowns(int value) {
touchdowns = value;
}
// TODO: add other setters for each private field
#Override
public String toString() {
return String.format("Player %s has QB rating %s", name, calculateQbRating());
}
}
Your application (this is not called a test):
class NFLApplication {
public static void main(String[] args) {
NFLPlayer playerStats = new NFLPlayer("johnson");
playerStats.setTouchdowns(2);
playerStats.setPassingAttempts(44);
playerStats.setPassingYards(285);
playerStats.setInterceptions(1);
playerStats.setCompletedPasses(35);
double qbRating = playerStats.calculateQbRating();
System.out.println(qbRating);
}
}
A test for your NFLPlayer class using the JUnit framework (JUnit is usually included by default within your IDE):
public class NFLPlayerTest {
// instance of the class-under-test
private NFLPlayer instance;
// set up method executed before each test case is run
#Before
public void setUp() {
instance = new NFLPlayer();
}
#Test
public void testCalculateQbRatingHappy() {
// SETUP
instance.setTouchdowns(2);
instance.setPassingAttempts(44);
instance.setPassingYards(285);
instance.setInterceptions(1);
instance.setCompletedPasses(35);
// CALL
double result = playerStats.calculateQbRating();
// VERIFY
// assuming here the correct result is 42.41, I really don't know
assertEquals(42.41, result);
}
#Test
public void testCalculateQbRatingZeroPassingAttempts() {
// SETUP
// passingAttempts=0 is not handled gracefully by your logic (it causes an ArithmeticException )
// you will probably want to fix this
instance.setPassingAttempts(0);
// CALL
double result = playerStats.calculateQbRating();
// VERIFY
// assuming here that you will return 0 when passingAttempts=0
assertEquals(0, result);
}
}
This test class should go in your test source directory (normally in yourproject/src/test/yourpackage/). It requires some imports which should be easily resolvable within the IDE since JUnit is usually available by default.
To run the test, right click on it and select something like 'Run test', 'Test file' or the like, depending on which IDE you are using (IDE's are development tools such as Eclipse, NetBeans or IntelliJ). You should see some test output indicating if the test succeeded (green) or if there were failures (red). Having such tests is useful because it forces you think about your design and write better code. (testable code is usually better than hard-to-test code) and because it warns you if new changes cause bugs in existing code (regression).
EDIT:
To create two players with different stats you have to create two instances (I added a name field so we can more easily distinguish the players):
NFLPlayer player1 = new NFLPlayer("adams");
NFLPlayer player2 = new NFLPlayer("jones");
And give them each their own statistics:
player1.setTouchdowns(2);
player1.setPassingAttempts(4);
player1.setPassingYards(6);
player1.setInterceptions(8);
player1.setCompletedPasses(10);
player2.setTouchdowns(1);
player2.setPassingAttempts(3);
player2.setPassingYards(5);
player2.setInterceptions(7);
player2.setCompletedPasses(9);
You could even create a list of players:
List<NFLPlayer> players = new ArrayList<>();
players.add(player1);
players.add(player2);
And then you could for instance print out all player ratings in a loop:
for(NFLPlayer player : players) {
// this uses the `toString` method I added in NFLPlayer
System.out.println(player);
}
you should not call the method name inside SOP instead System.out.println(playerStats.QBRating(touchdowns, passingAttempts, completedPasses,
passingYards, interceptions));
or override toString() method in your class and assign the method call to a local variable and print the value.
Also use some frameworks(Junit) instead of writing stubs
I had to create this point program a year ago, a year ago it worked fine. Now I have to revisit it and upon compiling and trying to run it I ran into the error of the fact that an abstract class cannot be instantiated. I have done some looking around online and figured out that some update or sort with Java has made it where the method of using PointClass point1 = new PointClass(); is no longer valid and will through an error.
I have yet to find an answer for fixing the error when trying to instantiate the class using a driver program. I also saw that in order to use an abstract class now, a subclass must be present. The thing is is that due to the instructions of the program I cannot use a subclass. Only the driver and the point class.
The program is very simple, just declare some points and call them from the abstract class in order to print to the screen. I need some help on figuring out the updated method to make this work again without the instantiated error.
The PointClass
public abstract class PointClass {
private int pointX;
private int pointY;
//set instance variables
public PointClass() { this.pointX = 10; this.pointY = 10; }
public PointClass(int x, int y){ this.pointX = x; this.pointY = y; }
//make getters and setters
public void setPointX(int x) { this.pointX = x; }
public void setPointY(int y) { this.pointY = y; }
public int getPointX() { return this.pointX; }
public int getPointY() { return this.pointY; }
//make string for format with driver
public String toString() { return "x = " + this.pointX + " y = " + this.pointY; }
}
The Driver
public class PointTest {
public static void main(String[] args){
System.out.println();
PointClass point1 = new PointClass(); //set point1 as no argument
PointClass point2 = new PointClass(11, 24); // set point2 as argument with x and y
System.out.println("Point1: " + point1); //display point1 from toString method
System.out.println();
System.out.println("Point2: " + point2); //display point2 from toString method
System.out.println("---------------------");
}
}
The best thing to do would be to remove the abstract keyword. There's no need for it. Point has no abstract methods.
If you can't do that for whatever reason, you can create inline anonymous classes by adding curly braces after each instantiation:
PointClass point1 = new PointClass() { };
PointClass point2 = new PointClass(11, 24) { };
By the way, your claim that this used to work is incorrect. It has never been possible to directly instantiate an abstract class. That is in fact the entire point of the keyword, to prevent a class from being instantiated.
I keep getting cannot find symbol error when trying to create the subclass h object in my main code. Would someone please be able to help ? Thanks.
It seems like the main program is accepting the inhtt object but when I try to call h object it says that it cannot find symbol and asks me to create the h object.
public class inhtt {
//class methods
public int thing;
public int stuff ;
public int otherstuff;
// constructor based on parameters
public inhtt( int x, int y, int z){
thing = x;
stuff = y;
otherstuff = z;
}
void showmain (){
System.out.println("thing is " + thing);
System.out.println("stuff is " + stuff);
System.out.println("otherstuff is " + otherstuff);
}
public class h extends inhtt {
int beard;
h( int x, int y, int z, int a){
super(x,y,z);
beard = a;
}
void shownewa(){
System.out.println("beard is" +beard);
}
}
}
* #author New User
*/
public class runraffharsh {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
inhtt base = new inhtt(1,1,1);
base.showmain();
h = new h(1,1,1,1);
h.shownew();
// raff beard = new raff(1,1,1,1);
// beard.showbeard();
//
}
}
There are multiple problems with this code:
h is a inner class to inhtt. Since it is not static, you'll need to use something like base.new h(1,1,1,1); to instantiate it.
You need to declare a variable to assign your new h instance to. Try something like inhtt.h h = base.new h(1,1,1,1); for the whole line.
h (the class) has no method named shownew. It has a method named shownewa.
runraffharsh and inhtt are both public classes. They need to be in separate files.
The comment block at the top of runraffharsh is not opened properly.
You have problem with inherited class h's reference. And you defined showewa() but tried to access shownew()