We have a grading system that gets its data from an external source and writes the mean grade back to an external source. So now we have an indirect input source and an indirect output source. This makes it difficult for us to test the system.
Your task is to refactor the system so that we can test our grading system system.
The code for the grading system can be found in this zip file. We also provide an example csv file.
The code consists of three classes: Student
, GradeReader
and GradingSystem
.
Student
is a class to store the data about a student, including the grades.
GradeReader
reads the grade data from a file.
GradingSystem
is the program used to calculate the final grades, as show below. This is the logic that should be tested.
public class GradingSystem {
private GradeReader gradeReader;
public GradingSystem(GradeReader gradeReader) {
this.gradeReader = gradeReader;
}
public void calculateFinalGrades() {
// Read the grades from the file
List<Student> students = gradeReader.readGrades();
// Calculate the mean grade for each student
for (Student student : students) {
int sum = 0;
for (int grade : student.getGrades()) {
sum += grade;
}
int meanGrade = sum / student.getGrades().size();
// Replace the student's grades with the mean grade
student.getGrades().clear();
student.getGrades().add(meanGrade);
}
// Write the final grades back to the file
gradeReader.writeFinalGrades(students);
}
}
Here’s an example of how you might write a unit test for this system:
public class GradingSystemTest {
@Test
public void testCalculateFinalGrades() {
// Use the mock grade file for testing
GradeReader reader = new GradeReader(...,...);
GradingSystem system = new GradingSystem(reader);
// Run the grading system and capture the output
system.calculateFinalGrades();
// Check that the output is as expected based on grades
assertEquals("Expected Output",....);
}
}
The problem is that we do not control the indirect input and cannot monitor the indirect output for the GradingSystem class. To make it possible to get control over this input we can make use of an interface. In the unit tests you can provide different implementations which will allow you to test the logic in the GradingSystem class.
Refactor the system so that we can test our GradingSystem
class. We want 100% line coverage on the GradingSystem class.
Hint: Everything is now completed in one big operation where we have no access to any of the intermediate steps.
The grading system can only read from CSV files. Add the possibility to also read grades from a JSON file and a database.