Description
Deliverables
Your project files should be submitted to the grading system by the due date and time specified. Note
that there is also an optional Skeleton Code assignment (ungraded) which will ensure that you have
classes and methods named correctly and also that you have the correct return types and parameter
types. This ungraded assignment will also indicate level of coverage your tests have achieved. The
files you submit to skeleton code assignment may be incomplete in the sense that method bodies have
at least a return statement if applicable or they may be essentially completed files. In order to avoid a
late penalty for the project, you must submit your files to the Completed Code assignment no later
than 11:59 PM on the due date. Your grade will be determined, in part, by the tests that you pass or
fail in your test file and by the level of coverage attained in your source file, as well as our usual
correctness tests.
Files to submit to the grading system:
• TriangularPrism.java, TriangularPrismTest.java
• TriangularPrismList.java, TriangularPrismListTest.java
Specifications – Use arrays in this project; ArrayLists are not allowed!
Overview: This project consists of four classes: (1) TriangularPrism is a class representing a
TriangularPrism object; (2) TriangularPrismTest class is a JUnit test class which contains one or more
test methods for each method in the TriangularPrism class; (3) TriangularPrismList is a class
representing a TriangularPrism list object; and (4) TriangularPrismListTest class is a JUnit test class
which contains one or more test methods for each method in the TriangularPrismList class. Note that
there is no requirement for a class with a main method in this project.
You should create a new folder to hold the files for this project and add your files from Part 2
(TriangularPrism.java file and TriangularPrismTest.java). You should create a new jGRASP project
for Part 3 and add TriangularPrism.java file and TriangularPrismTest.java to the project; you should
see the two files in their respective categories – Source Files and Test Files. If
TriangularPrismTest.java appears in source File category, you should right-click on the file and select
“Mark As Test” from the right-click menu. You will then be able to run the test file by clicking the
JUnit run button on the Open Projects toolbar. After TriangularPrismList.java and
TriangularPrismListTest.java are created as specified below, these should be added to your jGRASP
project for Part 3 as well.
If you have successfully completed TriangularPrism.java and TriangularPrismTest.java in Part
2, you should go directly to TriangularPrismList.java on page 6.
• TriangularPrism.java (The specification of the TriangularPrism class is repeated below for your
convenience from Part 2; there are no modifications for this class in Part 3)
Requirements: Create a TriangularPrism class that stores the label, triangle edge, and prism
height (edge and height are non-negative, >= 0). The TriangularPrism class also includes
methods to set and get each of these fields, as well as methods to calculate the triangle area,
rectangle area, surface area, and volume of a TriangularPrism object, and a method to provide a
Project: TriangularPrism with JUnit Tests – Part 3 Page 2 of 9
Page 2 of 9
String value that describes a TriangularPrism object. The TriangularPrism class includes a one
static field (or class variable) to track the number of TriangularPrism objects that have been
created, as well appropriate static methods to access and reset this field. And finally, this class
provides a method that JUnit will use to test TriangularPrism objects for equality as well as a
method required by Checkstyle. In addition, TriangularPrism must implement the Comparable
interface for objects of type TriangularPrism.
A uniform TriangularPrism is a TriangularPrism in which the faces (bottom and top) are equilateral
triangles (a = b = c) with side edge length a. When lying on a triangle face, the prism has height h.
The sides of the prism are three rectangles of the same size. (https://en.wikipedia.org/wiki/Triangular_prism)
The variables are
abbreviated as follows:
� is triangle edge length
� is height of prism
�� is triangle area
�� is rectangle area
A is total surface area
V is volume
�# = 0.25*3�$
�% = �ℎ
� = 2�# + 3�%
� = �#ℎ
Design: The TriangularPrism class implements the Comparable interface for objects of type
TriangularPrism and has fields, a constructor, and methods as outlined below (last method is
new).
(1) Fields: Instance Variables – label of type String, edge of type double, and height of type
double. Initialize the String to “” and the double variables to 0 in their respective
declarations. These instance variables should be private so that they are not directly
accessible from outside of the TriangularPrism class, and these should be the only instance
variables (fields) in the class.
Class Variable – count of type int should be private and static, and it should be initialized to
zero.
(2) Constructor: Your TriangularPrism class must contain a public constructor that accepts three
parameters (see types of above) representing the label, edge, and height. Instead of assigning
the parameters directly to the fields, the respective set method for each field (described
below) should be called since they are checking the validity of the parameter. For example,
instead of using the statement label = labelIn; use the statement
setLabel(labelIn); The constructor should increment the class variable count each
time a TriangularPrism is constructed.
Below are examples of how the constructor could be used to create TriangularPrism objects.
Note that although String and numeric literals are used for the actual parameters (or
Project: TriangularPrism with JUnit Tests – Part 3 Page 3 of 9
Page 3 of 9
arguments) in these examples, variables of the required type could have been used instead of
the literals.
TriangularPrism ex1 = new TriangularPrism(“Small Example”, 1.8, 3.25);
TriangularPrism ex2 = new TriangularPrism(” Medium Example “, 10.7, 25.4);
TriangularPrism ex3 = new TriangularPrism(“Large Example”, 45.47, 105.0);
(3) Methods: Usually a class provides methods to access and modify each of its instance
variables (known as get and set methods) along with any other required methods. The
methods for TriangularPrism, which should each be public, are described below. See the
formulas in the figure above and the Code and Test section below for information on
constructing these methods.
o getLabel: Accepts no parameters and returns a String representing the label field.
o setLabel: Takes a String parameter and returns a boolean. If the String
parameter is not null, then the “trimmed” String is set to the label field and the
method returns true. Otherwise, the method returns false and the label is not set.
o getEdge: Accepts no parameters and returns a double representing the edge field.
o setEdge: Takes a double parameter and returns a boolean. If the double
parameter is non-negative, then the parameter is set to the edge field and the method
returns true. Otherwise, the method returns false and the edge field is not set.
o getHeight: Accepts no parameters and returns a double representing the height
field.
o setHeight: Takes a double parameter and returns a boolean. If the double
parameter is non-negative, then the parameter is set to the height field and the method
returns true. Otherwise, the method returns false and the height field is not set.
o triangleArea: Accepts no parameters and returns the double value for the area of
one of the triangular faces of the prism.
o rectangleArea: Accepts no parameters and returns the double value for area of
one of the rectangle sides of the prism.
o surfaceArea: Accepts no parameters and returns the double value for the total
surface area of the TriangularPrism.
o volume: Accepts no parameters and returns the double value for the volume of the
TriangularPrism.
o toString: Returns a String containing the information about the TriangularPrism
object formatted as shown below, including decimal formatting (“#,##0.0##”) for the
double values. Newline and tab escape sequences should be used to achieve the proper
layout within the String but it should not begin or end with a newline. In addition to the
field values (or corresponding “get” methods), the following methods should be used to
compute appropriate values in the toString method: rectangleArea(),
triangelArea(), and surfaceArea(), and volume(). Each line should have
no trailing spaces (e.g., there should be no spaces before a newline (\n) character). The
Project: TriangularPrism with JUnit Tests – Part 3 Page 4 of 9
Page 4 of 9
toString value for ex1, ex2, and ex3 respectively are shown below (the blank lines
are not part of the toString values).
TriangularPrism “Small Example” with triangle edge of 1.8 units
and prism height of 3.25 units has:
triangle area = 1.403 square units
rectangle area = 5.85 square units
surface area = 20.356 square units
volume = 4.56 cubic units
TriangularPrism “Medium Example” with triangle edge of 10.7 units
and prism height of 25.4 units has:
triangle area = 49.576 square units
rectangle area = 271.78 square units
surface area = 914.491 square units
volume = 1,259.221 cubic units
TriangularPrism “Large Example” with triangle edge of 45.47 units
and prism height of 105.0 units has:
triangle area = 895.263 square units
rectangle area = 4,774.35 square units
surface area = 16,113.576 square units
volume = 94,002.595 cubic units
o getCount: A static method that accepts no parameters and returns an int representing
the static count field.
o resetCount: A static method that returns nothing, accepts no parameters, and sets the
static count field to zero.
o equals: An instance method that accepts a parameter of type Object and returns false if
the Object is a not a TriangularPrism; otherwise, when cast to a TriangularPrism, if it has
the same field values as the TriangularPrism upon which the method was called, it returns
true. Otherwise, it returns false. Note that this equals method with parameter type Object
will be called by the JUnit Assert.assertEquals method when two TriangularPrism objects
are checked for equality.
Below is a version you are free to use.
public boolean equals(Object obj) {
if (!(obj instanceof TriangularPrism)) {
return false;
}
else {
TriangularPrism d = (TriangularPrism) obj;
return (label.equalsIgnoreCase(d.getLabel())
&& (Math.abs(edge – d.getEdge()) < .000001)
&& (Math.abs(height – d.getHeight()) < .000001));
}
}
o hashCode(): Accepts no parameters and returns zero of type int. This method is
required by Checkstyle if the equals method above is implemented.
o compareTo: Accepts a parameter of type TriangularPrism and returns an int as
follows: a negative value if this.volume() is less than the parameter’s volume; a
Project: TriangularPrism with JUnit Tests – Part 3 Page 5 of 9
Page 5 of 9
positive value if this.volume() is greater than the parameter’s volume; zero if the
two volumes are essentially equal. For a hint, see the activity for this module.
Code and Test: As you implement the methods in your TriangularPrism class, you should
compile it and then create test methods as described below for the TriangularPrismTest class.
• TriangularPrismTest.java
Requirements: Create a TriangularPrismTest class that contains a set of test methods to test each
of the methods in TriangularPrism. The goal for Part 2 is method, statement, and condition
coverage.
Design: Typically, in each test method, you will need to create an instance of TriangularPrism,
call the method you are testing, and then make an assertion about the expected result and the
actual result (note that the actual result is commonly the result of invoking the method unless it
has a void return type). You can think of a test method as simply formalizing or codifying what
you could be doing in jGRASP interactions to make sure a method is working correctly. That is,
the sequence of statements that you would enter in interactions to test a method should be entered
into a single test method. You should have sufficient test methods so that each method,
statement, and condition in TriangularPrism are covered. Collectively, these test methods are a
set of test cases that can be invoked with a single click to test all of the methods in your
TriangularPrism class.
Code and Test: A good strategy would be to begin by writing test methods for those methods in
TriangularPrism that you “know” are correct. By doing this, you will be able to concentrate on
the getting the test methods correct. That is, if the test method fails, it is most likely due to a
defect in the test method itself rather the TriangularPrism method being testing. As you become
more familiar with the process of writing test methods, you will be better prepared to write the
test methods as new methods are developed. Be sure to call the TriangularPrism toString
method in one of your test methods and assert something about the return value. If you do not
want to use assertEquals, which would require the return value match the expected value exactly,
you could use assertTrue and check that the return value contains the expected value. For
example, for TriangularPrism example3:
Assert.assertTrue(example3.toString().contains(“\”Large Example\””));
Also, remember that you can set a breakpoint in a JUnit test method and run the test file in Debug
mode. Then, when you have an instance in the Debug tab, you can unfold it to see its values or
you can open a canvas window and drag items from the Debug tab onto the canvas. You can also
step-in to the method being called by the test method and then single-step through it, looking for
the error.
Project: TriangularPrism with JUnit Tests – Part 3 Page 6 of 9
Page 6 of 9
• TriangularPrismList.java (new for Part 3) – Consider implementing this file in parallel with its
test file, TriangularPrismListTest.java, which is described after this class.
Requirements: Create a TriangularPrismList class that stores the name of the list and an array of
TriangularPrism objects. It also includes methods that return the name of the list, number of
TriangularPrism objects in the TriangularPrismList, total surface area, total volume, average
surface area, and average volume for all TriangularPrism objects in the TriangularPrismList. The
toString method returns summary information about the list (see below).
Design: The TriangularPrismList class has three fields, a constructor, and methods as outlined
below.
(1) Fields (or instance variables): (1) a String representing the name of the list, (2) an array of
TriangularPrism objects, and (3) an int representing the number of TriangularPrism objects
in the array, which may be less than the length of the array of TriangularPrism objects. These
instance variables should be private so that they are not directly accessible from outside of the
TriangularPrismList class. These should be the only fields (or instance variables) in this
class, and they should be initialized in the constructor described below.
(2) Constructor: Your TriangularPrismList class must contain a constructor that accepts three
parameters: (1) a parameter of type String representing the name of the list, (2) a parameter of
type TriangularPrism[], representing the list of TriangularPrism objects, and (3) a
parameter of type int representing the number of TriangularPrism objects in the array.
These parameters should be used to assign the fields described above (i.e., the instance
variables).
(3) Methods: The methods for TriangularPrismList are described below.
o getName: Returns a String representing the name of the list.
o numberOfTriangularPrisms: Returns an int representing the number of
TriangularPrism objects in the TriangularPrismList. If there are zero TriangularPrism
objects in the list, zero should be returned.
o totalSurfaceArea: Returns a double representing the total surface areas for all
TriangularPrism objects in the list. If there are zero TriangularPrism objects in the list,
zero should be returned.
o totalVolume: Returns a double representing the total volumes for all TriangularPrism
objects in the list. If there are zero TriangularPrism objects in the list, zero should be
returned.
o averageSurfaceArea: Returns a double representing the average surface area for
all TriangularPrism objects in the list. If there are zero TriangularPrism objects in the
list, zero should be returned.
o averageVolume: Returns a double representing the average volume for all
TriangularPrism objects in the list. If there are zero TriangularPrism objects in the list,
zero should be returned.
Project: TriangularPrism with JUnit Tests – Part 3 Page 7 of 9
Page 7 of 9
o toString: Returns a String (does not begin with \n) containing the name of the list
(which can change depending on the name of the list passed as a parameter to the
constructor) followed by various summary items: number of TriangularPrisms, total
surface area, total volume, average surface area, and average volume. Use “#,##0.0##” as
the pattern to format the double values. Below is an example of the formatted String
returned by the toString method, where the name of the list (name field) is
TriangularPrism Test List and the array of TriangularPrism objects contains
the three examples described above (top of page 3).
—– Summary for TriangularPrism Test List —–
Number of TriangularPrisms: 3
Total Surface Area: 17,048.423 square units
Total Volume: 95,266.376 cubic units
Average Surface Area: 5,682.808 square units
Average Volume: 31,755.459 cubic units
o getList: Returns the array of TriangularPrism objects (the second field above).
o addTriangularPrism: Returns nothing but takes three parameters (label, edge, and
height), creates a new TriangularPrism object, and adds it to the TriangularPrismList
object. Be sure to increment the int field containing the number of TriangularPrism
objects in the TriangularPrismList object.
o findTriangularPrism: Takes a label of a TriangularPrism as the String parameter
and returns the corresponding TriangularPrism object if found in the TriangularPrismList
object; otherwise returns null. Case should be ignored when attempting to match the
label.
o deleteTriangularPrism: Takes a String as a parameter that represents the label of
the TriangularPrism and returns the TriangularPrism if it is found in the
TriangularPrismList object and deleted; otherwise returns null. Case should be ignored
when attempting to match the label. When an element is deleted from an array, elements
to the right of the deleted element must be shifted to the left. After shifting the items to
the left, the last TriangularPrism element in the array should be set to null. Finally, the
number of elements field must be decremented.
o editTriangularPrism: Takes three parameters (label, edge, and height), uses the label to
find the corresponding the TriangularPrism object in the list. If found, sets the edge and
height to the respective values passed in as parameters, and returns true. If not found,
returns false.
(Note that the label should not be changed by this method.)
o findTriangularPrismWithLargestVolume: Returns the TriangularPrism with
the largest volume; if the list contains no TriangularPrism objects, returns null.
Code and Test: Some of the methods above require that you use a loop to go through the objects
in the array. You should implement the class below in parallel with this one to facilitate testing.
That is, after implementing one to the methods above, you can implement the corresponding test
method in the test file described below.
Project: TriangularPrism with JUnit Tests – Part 3 Page 8 of 9
Page 8 of 9
• TriangularPrismListTest.java (new for Part 3) – Consider implementing this file in parallel
with its source file, TriangularPrismList.java, which is described above this class.
Requirements: Create a TriangularPrismListTest class that contains a set of test methods to test
each of the methods in TriangularPrismList.
Design: Typically, in each test method, you will need to create an instance of
TriangularPrismList, call the method you are testing, and then make an assertion about the
expected result and the actual result (note that the actual result is usually the result of invoking
the method unless it has a void return type). You can think of a test method as simply
formalizing or codifying what you have been doing in interactions to make sure a method is
working correctly. That is, the sequence of statements that you would enter in interactions to test
a method should be entered into a single test method. You should have at least one test method
for each method in TriangularPrismList. However, if a method contains conditional statements
(e.g., an if statement) that results in more than one distinct outcome, you need a test method for
each outcome. For example, if the method returns boolean, you should have one test method
where the expected return value is false and another test method that expects the return value to
be true. Also, each condition in boolean expression must be exercised true and false.
Collectively, these test methods are a set of test cases that can be invoked with a single click to
test all the methods in your TriangularPrismList class.
Code and Test: A good strategy would be to begin by writing test methods for those methods in
TriangularPrismList that you “know” are correct. By doing this, you will be able to concentrate
on the getting the test methods correct. That is, if the test method fails, it is most likely due to a
defect in the test method itself rather the TriangularPrismList method being testing. As you
become more familiar with the process of writing test methods, you will be better prepared to
write the test methods for the new methods in TriangularPrismList. Be sure to call the
TriangularPrismList toString method in one of your test cases so that the grading system will
consider the toString method to be “covered” in its coverage analysis. Remember that when a
test method fails, you can set a breakpoint in a JUnit test method and run the test file in Debug
mode. Then, when you have an instance in the Debug tab, you can unfold it to see its values or
you can open a canvas window and drag items from the Debug tab onto the canvas. You can also
step-in to the method being called by the test method and then single-step through it, looking for
the error.
Finally, when comparing two arrays for equality in JUnit, be sure to use Assert.assertArrayEquals
rather than Assert.assertEquals. Assert.assertArrayEquals will return true only if the two arrays
are the same length and the elements are equal based on an element by element comparison using
the equals method.
Project: TriangularPrism with JUnit Tests – Part 3 Page 9 of 9
Page 9 of 9
The Grading System
When you submit your files (TriangularPrism.java, TriangularPrismTest.java, TriangularPrismList.java,
and TriangularPrismListTest.java), the grading system will use the results of your test methods and their
level of coverage of your source files as well as the results of our reference correctness tests to determine
your grade. In this project, your test files should provide method, statement, and condition coverage.
Each condition in your source file must be exercised both true and false. See below for a description of
how to test a boolean expression with multiple conditions.
Note For Testing the equals Method in TriangularPrism
Perhaps the most complicated method to test is the equals method in TriangularPrism. This method has
three conditions in the boolean expression that are &&’d. Since Java (and most other languages) uses
short-cut logic, if the first condition in an && is false, the &&’d expression is false. This means that to
test the second condition, the first conditions must be true. Furthermore, to test the third conditions both
the first and second conditions must be true. To have condition coverage for the equals method, you need
the four test cases where the three conditions evaluate to the following, where T is true, F is false, and X
is don’t care (could be true or false):
FXX – returns false
TFX – returns false
TTF – returns false
TTT – returns true