Week 7
In IntelliJ, right-click the Fraction class title and choose "Show Context Options" then "Create Test".
JUnit 5 will be pre-selected, because it is installed in pom.xml
Check the "setUp/@Before" box. Click the check boxes next to all of the methods.
The FractionTest class is successfully added to the tests folder.
Fully-qualified annotations ("@org.junit.jupiter.api.BeforeEach" and "@org.junit.jupiter.api.Test") only need to be @BeforeEach and @Test.
If your annotations are fully-qualified press Ctrl + R to open the find and replace menu.
Replace all references of "@org.junit.jupiter.api." with "@".
Add an import statement for @BeforeEach and @Test.
Some Unit Tests require a default instance of the class.
The setUp method can be used to instantiate that object needed for each test.
Create two new Fraction objects as a private instance variables.
Instantiate the Fraction objects in the setUp method.
We want to keep our code DRY (Don't Repeat Yourself). If we don't use the setUp method we will have to instantiate a Fraction object inside of every single test method.
private Fraction f1;
private Fraction f2;
@BeforeEach
void setUp() {
f1 = new Fraction();
f2 = new Fraction(2, 3);
}
If you run the tests now, it should say all tests passed and you will see green checkmarks next to the method names in the bottom-left corner. We actually want all tests to fail by default.
Highlight a set of curly brackets on one of the tests.
Press Ctrl+Cmd+G (Mac) or Shift+Ctrl+Alt+J (Windows) to select all occurrences.
Use the arrow keys to position the cursors inside the curly brackets and type a fail method.
fail();
This is a static method from the Assertions class of JUnit.
Run the FractionTest class again to see that all tests failed. You will see orange X's next to the method names.
Study the assertEquals methods from JUnit's Assertions class.
Write tests for all of the getters and toString.
You should test all getter methods before setter methods so you can safely use the getter methods to verify that the setter methods work correctly.
When using the assertEquals method the first argument is the expected value and the second argument is the actual value.
The actual value will always come from a getter method.
When you run the tests, 3 will pass, the rest will fail.
@Test
void getNumerator() {
assertEquals(1, f1.getNumerator());
assertEquals(2, f2.getNumerator());
}
@Test
void getDenominator() {
assertEquals(1, f1.getDenominator());
assertEquals(3, f2.getDenominator());
}
@Test
void testToString() {
assertEquals("1/1", f1.toString());
assertEquals("2/3", f2.toString());
}
Next, we will write tests for all of the setters
For setNumerator, I am setting a positive, 0, and negative value. I am calling the getNumerator and toString methods to ensure equality.
For setDenominator, I am setting a positive, 0, and negative value. I am calling the getDenominator and toString methods to ensure equality.
Because the denominator cannot be 0, we use assertThrows. The lambda expression call's the Executable abstract method.
@Test
void setNumerator() {
f1.setNumerator(3);
assertEquals(3, f1.getNumerator());
assertEquals("3/1", f1.toString());
f1.setNumerator(0);
assertEquals(0, f1.getNumerator());
assertEquals("0/1", f1.toString());
f1.setNumerator(-3);
assertEquals(-3, f1.getNumerator());
assertEquals("-3/1", f1.toString());
}
@Test
void setDenominator() {
f1.setDenominator(3);
assertEquals(3, f1.getDenominator());
assertEquals("1/3", f1.toString());
f1.setDenominator(-3);
assertEquals(-3, f1.getDenominator());
assertEquals("-1/3", f1.toString());
}
Because the denominator cannot be 0, we use assertThrows.
The first argument is the type of Exception you expect to be thrown, in this case ArithmeticException.
The second argument is a lambda expression that call's the abstract method from the Executable functional interface.
assertThrows returns a Throwable object of type T, in this case ArithmeticException. You can assert the Exception message.
assertThrows(ArithmeticException.class, () -> f1.setDenominator(0));
ArithmeticException e = assertThrows(ArithmeticException.class, () -> f1.setDenominator(0));
assertEquals("cannot be zero", e.getMessage());
The following assertions seem logical, but they don't fully test it.
To correctly test the greatest common denominator of two integers, we must test for positive and negative values.
Adding the assertTrue method below will currently fail.
Update the Fraction class gcd method to return Math.abs(a).
@Test
void gcd() {
int result1 = Fraction.gcd(5, 7);
int result2 = Fraction.gcd(-5, 7);
int result3 = Fraction.gcd(5, -7);
int result4 = Fraction.gcd(-5, -7);
assertTrue(result1 == result2 && result2 == result3 && result3 == result4);
}
@Test
void gcd() {
assertEquals(15, Fraction.gcd(75, 45));
assertEquals(2, Fraction.gcd(2, 4));
assertEquals(1, Fraction.gcd(5, 7));
}
@Test
void simplify() {
f1.setNumerator(75);
f1.setDenominator(45);
f2 = f1.simplify();
assertEquals("5/3",f2.toString());
f1.setNumerator(2);
f1.setDenominator(4);
f2 = f1.simplify();
assertEquals("1/2",f2.toString());
f1.setNumerator(5);
f1.setDenominator(7);
f2 = f1.simplify();
assertEquals("5/7",f2.toString());
}
@Test
void simplify() {
f1.setNumerator(75);
f1.setDenominator(45);
f2 = f1.simplify();
assertEquals("5/3",f2.toString());
f1.setNumerator(2);
f1.setDenominator(4);
f2 = f1.simplify();
assertEquals("1/2",f2.toString());
f1.setNumerator(5);
f1.setDenominator(7);
f2 = f1.simplify();
assertEquals("5/7",f2.toString());
f1.setNumerator(-2);
f1.setDenominator(4);
f2 = f1.simplify();
assertEquals("-1/2",f2.toString());
f1.setNumerator(2);
f1.setDenominator(-4);
f2 = f1.simplify();
assertEquals("-1/2",f2.toString());
f1.setNumerator(-2);
f1.setDenominator(-4);
f2 = f1.simplify();
assertEquals("1/2",f2.toString());
}
@Test
void add() {
assertEquals("1 + 2/3 = 1 2/3", f1.add(f2));
f1.setNumerator(25);
f1.setDenominator(-100);
f2.setNumerator(-10);
f2.setDenominator(-15);
assertEquals("-1/4 + 2/3 = 5/12", f1.add(f2));
}
You must be physically present in class to take the midterm exam.
You cannot take the exam virtually.
You will randomly be assigned a CSV data set.
Read 3-4 fields from the CSV file to create a List of objects.
Get the objects with the highest/lowest value of an attribute.
Sort the List of objects by two attributes
You will randomly be assigned a conversion type.
Create a JSP to display a form that reads a single input and displays output.
Create a servlet that validates input and produces output.
Numbers cannot be negative
When finished, raise your hand and show the teacher your completed work.
Download the Covid-19 data set as tab-separated values (TSV) since some of the data contains commas.
Create a class called MidtermReview.
Create a class called CovidData
Create a static List<CovidData>
import java.util.*;
public class MidtermPractice {
private static List<CovidData> data = new ArrayList<>();
}
class CovidData {
private String countyName;
private String state;
private int totalCases;
public CovidData(String countyName, String state, int totalCases) {
this.countyName = countyName;
this.state = state;
this.totalCases = totalCases;
}
public String getCountyName() {
return countyName;
}
public void setCountyName(String countyName) {
this.countyName = countyName;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public int getTotalCases() {
return totalCases;
}
public void setTotalCases(int totalCases) {
this.totalCases = totalCases;
}
@Override
public String toString() {
return "CovidData [countyName=" + countyName + ", state=" + state + ", totalCases="
+ totalCases + "]";
}
public static Comparator<CovidData> compareTotalCases = Comparator.comparing(CovidData::getTotalCases);
}
Write a main method
Call FileInput.readAllLines method.
Convert lines in the List<String> to CovidData objects
Print the county with the highest total cases
Sort the data highest to lowest.
public static void main(String[] args) {
List<String> lines = FileInput.readAllLines("COVID-19.tsv");
// lines.forEach(System.out::println);
for(String line: lines) {
try {
String[] record = line.split("\t");
String countyName = record[1];
String state = record[2];
int totalCases = Integer.parseInt(record[4]);
data.add(new CovidData(countyName, state, totalCases));
} catch(NumberFormatException e) {
continue;
}
}
// data.forEach(System.out::println);
CovidData highest = data.stream().max(Comparator.comparing(CovidData::getTotalCases)).get();
System.out.println(highest);
Collections.sort(data, CovidData.compareTotalCases.reversed());
for(int i = 0; i < 10 ; i++) {
System.out.println(data.get(i));
}
}