When I was reading the test code I wrote four years ago, I realized that the intent of a certain Comparator test code was difficult to read. The content of the test is correct, but I couldn't imagine a specific use case by reading the test.
It's a good test code to some extent as it guarantees the correctness of the product code, but if possible, it would be happier if the maintainers of posterity could read the intention. So, I found a free time and tried to rewrite it.
In this article, we will introduce the old test code and the improved test code, and use it as a memorial service.
public class TodayReportComparator implements Comparator<Report> {
@Override
public int compare(Report lhs, Report rhs) {
//Good luck
}
}
TodayReportComparator is a Comparator that sorts today's reports in order to prioritize them.
Let's start with the conventional test. This test verifies the result of running Comparator # compare
.
public class TodayReportComparatorTest {
private TodayReportComparator sut;
@Before
public void setUp() {
sut = new TodayReportComparator();
}
@Test
public void Today's report comes to the top of yesterday's report() {
final long now = System.currentTimeMillis();
lhs = new Report(new Date(now));
rhs = new Report(new Date(now - 24 * 60 * 60 * 1000));
assertThat(sut.compare(lhs, rhs), lessThan(0)); //lhs is high
}
@Test
public void Today's report comes to the top of tomorrow's report() {
final long now = System.currentTimeMillis();
lhs = new Report(new Date(now));
rhs = new Report(new Date(now + 24 * 60 * 60 * 1000));
assertThat(sut.compare(lhs, rhs), lessThan(0)); //lhs is high
}
}
lhs
, rhs
), it looks like a Comparator test.Collections.sort
but no tests are written in that use caseIn any case, it's a story that you should remember the behavior of Java SE, or you can imagine it if you think about it for a moment. But from the reviewer's point of view, I honestly don't want to use my brain there too much.
In the newly rewritten test, I focused on what I wanted the result of Collections.sort
, which is the actual usage, to be.
public class TodayReportComparatorTest {
private TodayReportComparator sut;
@Before
public void setUp() {
sut = new TodayReportComparator();
}
@Test
public void Today's report comes to the top of yesterday's report() {
// Given
final long now = System.currentTimeMillis();
Report todayReport = new Report(new Date(now));
Report yesterdayReport = new Report(new Date(now - 24 * 60 * 60 * 1000));
List<Report> actual = Arrays.asList(
yesterdayReport,
todayReport
);
List<Report> expected = Arrays.asList(
todayReport, //The report dated today is at the top
yesterdayReport
);
// When
Collections.sort(actual, sut);
// Then
assertThat(actual, is(expected));
}
@Test
public void Today's report comes to the top of tomorrow's report() {
// Given
final long now = System.currentTimeMillis();
Report todayReport = new Report(new Date(now));
Report tomorrowReport = new Report(new Date(now + 24 * 60 * 60 * 1000));
List<Report> actual = Arrays.asList(
tomorrowReport,
todayReport
);
List<Report> expected = Arrays.asList(
todayReport, //The report dated today is at the top
tomorrowReport
);
// When
Collections.sort(actual, sut);
// Then
assertThat(actual, is(expected));
}
}
I wrote it according to my current taste. I think that the intention of "giving priority to today's report and bringing it up" that I originally wanted to do can be expressed in the test.
Currently, I have a habit of writing TDD when writing Java, and if I can write a test, I write the test first.
Test code is useful not only for the correctness of the product code, but also for expressing and refining the usability. It would be nice to be able to write test code that will help improve the product code.
Recommended Posts