How to run JUnit from the command line for TDD

Alonso Del Arte
18 min readApr 12, 2019

JUnit is so well-integrated with the major Java IDEs (Eclipse, NetBeans, IntelliJ) that you might be wondering: why would anyone even want to learn how to run JUnit from the command line?

I can only think of two reasons:

  1. So that you can honestly say you know how to do it, or
  2. So that you can do test-driven development (TDD) in Scala even if you don’t know how to set up your IDE for Scala (Eclipse or NetBeans — in my experience, using Scala in IntelliJ is very easy and intuitive).

If you can think of other reasons, please leave me a comment. The second reason might also apply to other programming languages for the Java Virtual Machine.

I am aware of the reason of not wanting to fire up an IDE just to run a couple of tests, but if you don’t already know how to run JUnit from the command line, learning how (and learning where the relevant JARs are at, and possibly setting up folders) will probably take you a lot longer than starting up your IDE, even on a sluggish computer.

This tutorial uses the second reason given above to motivate the example. Specifically, an implementation of the Fraction class in Scala, with the JUnit FractionTest also written in Scala.

Some of you might be thinking that JUnit is not the best testing framework for Scala, and you’re probably right. But for someone coming at Scala from a Java background, JUnit is perfect for me.

As I become more proficient with the functional side of Scala, I will probably become aware of JUnit’s shortcomings for testing Scala. But for now it’ll do just fine.

If you don’t care too much, or at all, about Scala, you can skim or skip the “What I will use to demonstrate” section, which I estimate will cut the reading time in half.

A few assumptions

If you’ve read this far, it would seem to be a fair assumption that you know Java and JUnit fairly well. That might not actually be the case, but I will assume that it is.

It would be wrong to assume that you know Scala. You might, but even if you don’t, I think that as long as I take care to explain the major departures from Java as they come up, you, as someone who knows Java, will have an easy time making sense of the superficial differences between Java and Scala.

I do assume that you know the basics of the command line in your computer’s operating system (e.g., the “DOS” command line in Windows), that you know how to navigate the directory structure, and that you know how to create subdirectories.

I also assume that you’re comfortable using some plaintext editor to type up programs, though I don’t assume what that editor might be. Vim? Sublime? Notepad? Something else?

And lastly, I assume you mostly use Eclipse or NetBeans for your Java development. If you use IntelliJ, you can just have it download the Scala for IntelliJ plugin, and then writing and running tests for Scala source is almost as easy as writing and running tests for Java source.

What I will use to demonstrate

For this tutorial, I will use the example of the Fraction class, an immutable data type for numbers like 1/2, −144/89, 29/12, −1729/53, etc., and its corresponding FractionTest.

It might feel like a toy example, but it’s a simple application of familiar mathematical concepts, and I’ve found it very useful for my own projects.

My Java version of Fraction provides the four basic operations of arithmetic (addition, subtraction, multiplication and division), and also reciprocal, and it implements java.lang.Comparable. It also overrides toString(), equals() and hashCode().

Our Scala version of Fraction will have those same capabilities, but we will name our basic arithmetic functions +(), -(), *() and /() instead of plus(), minus(), times() and divides() (but the tests will still be testPlus(), testMinus(), testTimes() and testDivides(), so as to avoid unnecessary confusion).

Also, we will need to implement scala.math.Ordered if we want to be able to use < and > to compare instances of Fraction (we can always use == in Scala since Scala will just call equals(), which, if nothing else, is available from java.lang.Object).

I’m also thinking about adding to() and by(), inspired by similar functions in Scala’s RichInt and Range classes. A thorough discussion of those will have to wait for another time, though.

So here’s the Scala source for Fraction that should fail all our initial tests, to be followed by a quick explanation of the major differences from Java that come up:

package fractionsobject Fraction {  import scala.language.implicitConversions  implicit def IntToFraction(n: Int) = new Fraction(0)  val HASH_SEP = 65536}class Fraction(numerator: Long, denominator: Long = 1L)
extends Comparable[Fraction] {
val fractNumer = numerator
val fractDenom = denominator
override def toString: String = "Not implemented yet" override def equals(obj: Any): Boolean = false override def hashCode: Int = 0 def +(addend: Fraction): Fraction = this def unary_- = new Fraction(-this.fractNumer, -this.fractDenom) def -(subtrahend: Fraction): Fraction = this def *(multiplicand: Fraction): Fraction = this def /(divisor: Fraction): Fraction = this def reciprocal: Fraction = this import java.util.ArrayList def to(end: Fraction): ArrayList[Fraction] = {
var range = new ArrayList[Fraction]
range.add(this)
range
}
def numericApproximation: Double = 0.0 override def compareTo(other: Fraction): Int = 0}

Yeah, that should fail all our tests. Before I present the tests, I will quickly discuss the major differences from Java that came up in the source listing above.

Notice that there is both a Fraction object and a Fraction class. The Fraction object is a “companion object” for the Fraction class.

If we put any “static fields” and/or “static methods” into the Java version of the Fraction class, in Scala we would put them in the Fraction companion object. In this example, that would be HASH_SEP, which you may or may not want to use to make hashCode() work correctly.

It is now my understanding that a class and its companion object must be in the same source file, which in this case would be Fraction.scala.

The Fraction companion object is also the place where we define implicit conversions from other types to Fraction. For more detail on implicit conversions in Scala, please see my article from February.

In Scala, you can place import statements in the scope where they make the most sense, rather than in the global scope of a source file, close to the top, like in Java.

In our example, the Fraction object doesn’t need java.util.ArrayList and the Fraction class doesn’t need scala.language.implicitConversions, so we can put one inside the class and the other inside the object. Sometimes we can drill down to even narrower scopes.

In a Java class, we can have multiple constructors scattered throughout the source, and we can claim that one of them is the primary constructor.

Though I suppose this makes sense in the case of chained constructors: the constructor with the most explicit parameters is the primary constructor. Or maybe the one with the fewest?

But in a Scala class, there really is a primary constructor, and it is “fused” with the class declaration. There is no need to explicitly call the superclass constructor, the Scala compiler takes care of that for us when necessary.

Default parameters help us reduce the need for alternate constructors. In the example, we have denominator: Long = 1L, which means that if the denominator is omitted, it will be assumed to be 1, and the fraction will be arithmetically equal to an integer.

Next, val is kind of like final in Java. Since numerator and denominator are both Long (which is kinda like the long primitive in Java, but with all the object-oriented amenities of the Long wrapper) and we assign them to the fields fractNumer and fractDenom, the Scala compiler automatically infers those are also Long. This helps cut down on “boilerplate.”

Since no one can modify fractNumer and fractDenom once Fraction is constructed, we’re not too worried about who can see what their values are, hence no need to set private.

Scala is said to automatically generate getters and setters, or getters only in the case of val fields like fractNumer and fractDenom

You know what? I think we should rename the constructor parameters numer and denom, and the val fields numerator and denominator. I believe that then that way the automatically generated getters have obvious names. In any case, there’s no need for us to write getNumerator() and getDenominator().

Here’s a taste of how that would work in the local Scala REPL:

scala> val oneHalf = new fractions.Fraction(1, 2)
oneHalf: fractions.Fraction = 1/2
scala> oneHalf.numerator
res57: Long = 1
scala> oneHalf.denominator
res58: Long = 2

In Scala, instead of the @Override annotation in Java, we use the override keyword. Why they couldn’t add the override keyword to the Java language is outside the scope of this article.

Here’s a seemingly superficial but important difference: to override equals(), the type of the object to be compared is Any, not Object. This one could cause you a confusing compilation error.

And lastly, we can use the characters +, -, *, / and many others as function names. This is one of those features that should only be used when it makes sense to do so, and in the case of a numeric data type like Fraction, it certainly does make sense.

The source listing above shows other departures from Java, but they can be dismissed with very quick remarks: semicolons are optional, as are curly braces for single-line blocks as well as parentheses for empty argument lists; and we write Generic[T] instead of Generic<T>.

As for the 2-space indentation, you can use four spaces if you prefer. As with most compilers, the Scala compiler generally does not care about extra whitespace, though it might be good to not split String literals across lines.

Now we can move to our tests.

package fractionsimport org.junit.Test
import org.junit.Assert._
class FractionTest { @Test def testImplicitConversion: Unit = {
val expected = new Fraction(49)
val sevenSixths = new Fraction(7, 6)
val actual = 42 * sevenSixths
assertEquals(expected, actual)
}
@Test def testFractionsToLowestTerms: Unit = {
val oneHalf = new Fraction(1, 2)
val twoQuarters = new Fraction(2, 4)
assertEquals(oneHalf, twoQuarters)
}
@Test def testDefaultDenomOne: Unit = {
val seven = new Fraction(7)
val sevenOneths = new Fraction(7, 1)
assertEquals(seven, sevenOneths)
}
@Test def testToString: Unit = {
val negOneHalf = new Fraction(-1, 2)
val expected = "-1/2"
val actual = negOneHalf.toString.replace(" ", "")
assertEquals(expected, actual)
}
@Test def testToStringDenomOneOmitted: Unit = {
val seven = new Fraction(7, 1)
val expected = "7"
val actual = seven.toString.replace(" ", "")
assertEquals(expected, actual)
}
@Test def testEquals: Unit = {
val oneHalf = new Fraction(1, 2)
val dupOneHalf = new Fraction(1, 2)
assertEquals(oneHalf, dupOneHalf)
val threeQuarters = new Fraction(3, 4)
assertNotEquals(oneHalf, threeQuarters)
}
@Test def testHashCode: Unit = {
val oneHalf = new Fraction(1, 2)
val twoQuarters = new Fraction(2, 4)
val oneHalfHashCode = oneHalf.hashCode
val twoQuartersHashCode = twoQuarters.hashCode
assertEquals(oneHalfHashCode, twoQuartersHashCode)
val threeQuarters = new Fraction(3, 4)
val threeQuartersHashCode = threeQuarters.hashCode
assertNotEquals(oneHalfHashCode, threeQuartersHashCode)
}
@Test def testPlus: Unit = {
val threeHalves = new Fraction(3, 2)
val fourSevenths = new Fraction(4, 7)
val expected = new Fraction(29, 14)
var actual = threeHalves + fourSevenths
assertEquals(expected, actual)
actual = fourSevenths + threeHalves // Commutative test
assertEquals(expected, actual)
}
@Test def testNegate: Unit = {
val threeHalves = new Fraction(3, 2)
val expected = new Fraction(-3, 2)
val actual = -threeHalves
assertEquals(expected, actual)
}
@Test def testMinus: Unit = {
val threeHalves = new Fraction(3, 2)
val fourSevenths = new Fraction(4, 7)
val expected = new Fraction(13, 14)
val actual = threeHalves - fourSevenths
assertEquals(expected, actual)
}
@Test def testTimes: Unit = {
val threeHalves = new Fraction(3, 2)
val fourSevenths = new Fraction(4, 7)
val expected = new Fraction(6, 7)
var actual = threeHalves * fourSevenths
assertEquals(expected, actual)
actual = fourSevenths * threeHalves // Commutative test
assertEquals(expected, actual)
}
@Test def testDivides: Unit = {
val threeHalves = new Fraction(3, 2)
val fourSevenths = new Fraction(4, 7)
val expected = new Fraction(21, 8)
val actual = threeHalves / fourSevenths
assertEquals(expected, actual)
}
@Test def testDivisionByZero: Unit = {
val threeHalves = new Fraction(3, 2)
val zero = new Fraction(0)
try {
val result = threeHalves / zero
val failMsg = "Trying to divide by zero should have caused an
exception, not given result " + result.toString
fail(failMsg)
} catch {
case iae: IllegalArgumentException => println("Trying to divide by zero correctly triggered IllegalArgumentException: " + iae.getMessage)
case ae: ArithmeticException => println("Trying to divide by zero correctly triggered ArithmeticException: " + ae.getMessage)
case e: Exception => fail(e.getMessage)
}
}
@Test def testReciprocal: Unit = {
val threeHalves = new Fraction(3, 2)
val expected = new Fraction(2, 3)
val actual = threeHalves.reciprocal
assertEquals(expected, actual)
}
@Test def testTo: Unit = {
import java.util.ArrayList
val fourSevenths = new Fraction(4, 7)
val threeHalves = new Fraction(3, 2)
val expected = new ArrayList[Fraction]
for (n <- 8 to 21) expected.add(new Fraction(n, 14))
val actual = fourSevenths to threeHalves
assertEquals(expected, actual)
}
@Test def testNumericApproximation: Unit = {
val oneSeventh = new Fraction(1, 7)
var expected = 0.14285714
val testDelta = 0.00000001
var actual = oneSeventh.numericApproximation
assertEquals(expected, actual, testDelta)
val thirteenFiftyeights = new Fraction(13, 58)
expected = 0.22413793
actual = thirteenFiftyeights.numericApproximation
assertEquals(expected, actual, testDelta)
}
@Test def testCompareTo: Unit = {
fail("The test case is a prototype")
}
}

A couple of things to note: what’s void in Java is Unit in Scala (I don’t like it, but that’s how it is). And, although we can write things like summandA.+(summandB), it makes far more sense to write summandA + summandB.

You probably already figured out that var is just like val, except that we can change the value of a var later on. Just as with val, with var we don’t need to specify the type on the left of the equal sign if it can be readily inferred from the expression to the right of the equal sign.

One superficial difference is that the wildcard character for imports is the underscore rather than the asterisk.

If you prefer to write “@Test” on a line by itself, you certainly can. Aside from these differences, using JUnit for Scala sources should feel pretty much the same as using JUnit for Java sources.

Now to actually run JUnit from the command line

Oh, wait, not just yet. First we have to compile the source and tests. And, at least the first time, it will be necessary to compile the source first and then the tests.

I don’t see any point trying to compile something (the test) you already know will fail to compile (if the source is not present yet).

I thought it would be a good idea to replicate the directory structure the IDE uses. In hindsight, however, I should have gone with a simpler directory structure.

Taking NetBeans for Windows as a model, and reckoning from the project root folder, we will put source files in the src folder, test files in the test folder, compiled source in the build\classes folder and compiled tests in the build\test\classes folder.

In each of those, there should be separate subfolders for the separate packages, which here means src\fractions, test\fractions, build\classes\fractions and build\test\classes\fractions.

So, in the command line, go to src\fractions and give the command

scalac -d ..\..\build\classes Fraction.scala

If you’d prefer to follow along with Java source and tests, it would be much the same thing except you’d use javac instead of scalac.

Note that you don’t have to specify build\classes\fractions since the compiler will automatically place Fraction.class and Fraction$.class in the fractions folder, or create it if it’s not already there (I think that Fraction$.class corresponds to the Fraction companion object).

But if you do specify it, you’ll wind up with an extra level in the hierarchy. Hopefully there are no compilation errors or warnings to deal with.

Next, we need to compile the tests. Now it gets quite a bit more complicated. First, to make FractionTest.class, the compiler obviously needs to access Fraction.class.

And, just as importantly, the compiler needs to access the JUnit JAR. On my NetBeans installation, the path to the JUnit JAR is C:\Program Files\NetBeans 8.2\platform\modules\ext\junit-4.12.jar.

Go to test\fractions, then give the command

scalac -classpath "C:\Program Files\NetBeans 8.2\platform\modules\ext\junit-4.12.jar";..\..\build\classes -d ..\..\build\test\classes FractionTest.scala

Once we’ve got source and tests compiled, we’re finally ready to run JUnit from the command line. Go to build\test\classes.

Actually, there is just one more detail: we also need the Hamcrest matchers JAR. Conveniently for me, on my NetBeans installation, the Hamcrest Core 1.3 JAR is in the same directory as the JUnit 4.12 JAR.

Another wrinkle is that apparently we also need scala-library.jar. This is not a problem for those following along with Java only.

After a lot of frustration, I decided that trying to have the source class in one directory and the test class in another directory was way more trouble than it was worth. Especially since all the tutorials I could find put source and test classes on the same directory.

It seems that since FractionTest is declared to be in the fractions package, and FractionTest.class is in build\test\classes\fractions, JUnit expects Fraction.class and Fraction$.class to also be in build\test\classes\fractions. JUnit won’t look elsewhere in the class path.

Unless maybe there is some option I don’t know about that permits source classes and test classes to be in separate folders. Trying to replicate the IDE’s project directory structure creates way too much overhead for a human being typing things at the command line.

So I copied Fraction.class and Fraction$.class from build\classes\fractions to build\test\classes\fractions. Then, from build\test\classes (not build\test\classes\fractions), I put in this long command:

java -cp .;"C:\Program Files\NetBeans 8.2\platform\modules\ext\junit-4.12.jar";"C:\Program Files\NetBeans 8.2\platform\modules\ext\hamcrest-core-1.3.jar";"C:\Program Files (x86)\scala\lib\scala-library.jar" org.junit.runner.JUnitCore fractions.FractionTest

But here I ran into yet another problem. With all the failures (since every test ought to be failing at this point), the output was very long and cmd.exe is not letting me see all of it. The window only lets me scroll up to a certain point in the middle of the output.

I remembered from the old days of DOS that it’s possible to reroute the output to a text file. After dusting off an old DOS reference, I tried a slightly different version of the previous command:

java -cp .;"C:\Program Files\NetBeans 8.2\platform\modules\ext\junit-4.12.jar";"C:\Program Files\NetBeans 8.2\platform\modules\ext\hamcrest-core-1.3.jar";"C:\Program Files (x86)\scala\lib\scala-library.jar" org.junit.runner.JUnitCore fractions.FractionTest > testResults.txt

Finally, I was able to see that the tests failing for the right reasons (I’ve bolded some things above and below to make it easier to skim — I’ve also omitted several lines so as to not bloat my word count too much).

JUnit version 4.12
.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E
Time: 3.377
There were 16 failures:
1) testImplicitConversion(fractions.FractionTest)
java.lang.AssertionError: expected: fractions.Fraction<Not implemented yet> but was: fractions.Fraction<Not implemented yet>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
...several lines omitted...
2) testDefaultDenomOne(fractions.FractionTest)
java.lang.AssertionError: expected: fractions.Fraction<Not implemented yet> but was: fractions.Fraction<Not implemented yet>
...several lines omitted...
3) testMinus(fractions.FractionTest)
java.lang.AssertionError: expected: fractions.Fraction<Not implemented yet> but was: fractions.Fraction<Not implemented yet>
...several lines omitted...
4) testTimes(fractions.FractionTest)
java.lang.AssertionError: expected: fractions.Fraction<Not implemented yet> but was: fractions.Fraction<Not implemented yet>
...several lines omitted...
16) testNegate(fractions.FractionTest)
java.lang.AssertionError: expected: fractions.Fraction<Not implemented yet> but was: fractions.Fraction<Not implemented yet>
...several lines omitted...
FAILURES!!!
Tests run: 16, Failures: 16

The output shown above was missing a test for numericApproximation(). It would have failed, just like all the others. This is the right outcome for the first run of the test suite.

Our first priority now should be to get testEquals() to pass, since almost all the tests depend on equals() working correctly.

The IDE-generated Java equals() in NetBeans would start out by checking this == obj and this == null, then there’s a getClass() comparison. If those are inconclusive, the relevant fields are compared, but it has to do a cast first.

We could just translate that algorithm to Scala, or we could try to write something a bit more idiomatic:

  override def equals(obj: Any): Boolean = obj match {
case obj: Fraction => {
this.numerator == obj.numerator &&
this.denominator == obj.denominator
}
case _ => false
}

In Scala, we can do a sort of “switch-case” on the type of an object. Once we ascertain that obj is an instance of Fraction, there is no need to create a final copy of obj cast to Fraction like in Java; we can go ahead and work on obj just the same as if we had declared it as Fraction in the current scope.

Then “case _ =>” is like “default:” in a Java switch statement (but there is no need for break in the previous cases).

Presumably if obj is not of type Fraction, it can’t be equal to this. Hence case _ => false. I’m not sure if this would work correctly with a subclass of Fraction, but if that ever becomes necessary, we should write a test, run that test and go from there.

At this point we shouldn’t concern ourselves with the program recognizing as equal fractions that are arithmetically equal but not in lowest terms (e.g., 1/2 = 2/4). We do already have a test for that, but it’s separate from testEquals.

Maybe at this point we should also get testToString() to pass, since “Not implemented yet” is almost as annoying as the default Object.toString(), and neither is as informative as “numerator/denominator”.

Go ahead and change equals() to what I wrote above. I think you can figure out toString() on your own, but only work on making testToString() pass, leave testToStringDenomOneOmitted() for later.

Once you make these changes to the source, be sure to save in your text editor, since it probably doesn’t have auto-save like IntelliJ.

You also have to recompile the source. If you get the same failures as before, check that you did save the changes to the source (that’s from personal experience).

Thank goodness for the Up arrow keyboard shortcut in the command line, so that you don’t have to keep typing the same commands with the same lengthy class paths.

With the changes made and saved, and the source recompiled, we can run the tests again. Only two tests should pass.

Hmm… I seem to have made some sort of mistake, since five of the tests pass (once again I’ve bolded the test names to facilitate skimming the results, and also I’ve omitted the stack traces without comment):

JUnit version 4.12
.E.E..E.E.E.E...E.E.E.E.E.E..
Time: 1.86
There were 12 failures:
1) testImplicitConversion(fractions.FractionTest)
java.lang.AssertionError: expected:<49/1> but was:<0/1>
2) testNumericApproximation(fractions.FractionTest)
java.lang.AssertionError: expected:<0.14285714> but was:<0.0>
3) testMinus(fractions.FractionTest)
java.lang.AssertionError: expected:<13/14> but was:<3/2>
4) testTimes(fractions.FractionTest)
java.lang.AssertionError: expected:<6/7> but was:<3/2>
5) testFractionsToLowestTerms(fractions.FractionTest)
java.lang.AssertionError: expected:<1/2> but was:<2/4>
6) testPlus(fractions.FractionTest)
java.lang.AssertionError: expected:<29/14> but was:<3/2>
7) testTo(fractions.FractionTest)
java.lang.AssertionError: expected:<[8/14, 9/14, 10/14, 11/14, 12/14, 13/14, 14/14, 15/14, 16/14, 17/14, 18/14, 19/14, 20/14, 21/14]> but was:<[4/7]>
8) testCompareTo(fractions.FractionTest)
java.lang.AssertionError: The test case is a prototype
9) testToStringDenomOneOmitted(fractions.FractionTest)
org.junit.ComparisonFailure: expected:<7[]> but was:<7[/1]>
10) testDivisionByZero(fractions.FractionTest)
java.lang.AssertionError: Trying to divide by zero should have caused an exception, not given result 3/2
11) testHashCode(fractions.FractionTest)
java.lang.AssertionError: Values should be different. Actual: 0
12) testDivides(fractions.FractionTest)
java.lang.AssertionError: expected:<3/56> but was:<3/2>
FAILURES!!!
Tests run: 17, Failures: 12

With toString() implemented, we can see that our program is not automatically putting fractions in lowest terms.

I just noticed that I neglected to put in a test that says denominator zero for the constructor should cause an exception. Without that requirement on the constructor, it would be possible to create a fraction with an invalid denominator that causes some unexpected problems down the line.

Negative denominators should be allowed, however. But the constructor should change negative denominators to positive denominators, by multiplying the supplied numerator by −1.

So, for example, new Fraction(1, -2) should be a fraction with numerator −1 and denominator 2, while new Fraction(-1, -2) should be a fraction with numerator 1 and denominator 2.

Now that some tests are passing, I’m really missing the green checkmarks in the IDE, as they make it easier to see which tests did pass.

Also, I like how the IDEs report only the pertinent lines of the stack trace. For example, the line numbers in org.junit.runners.ParentRunner$3 are useless to me; I really only care about the lines that I can rewrite.

However, I have to admit that I do find it just a little interesting to know that sun.reflect.NativeMethodAccessorImpl.invoke0 is a “native method” but sun.reflect.NativeMethodAccessorImpl.invoke is from an “unknown source.”

Given how laborious this cycle of saving, recompiling and rerunning is, it’s understandable if you would prefer to make several tests pass at once rather than one at a time.

IntelliJ makes it so easy to just run one test at a time. And even in NetBeans it doesn’t take too long to run a whole test class, provided you haven’t made any test too long.

So if you want to continue this exercise on the command line, I suggest you fix the implicit conversion (it suffices to change just one character), figure out how to put fractions in lowest terms, and fix the arithmetic functions.

If you want to work on hashCode(), recall that I put in HASH_SEP as a val in the Fraction object, essentially making it what in Java would be public static final.

If, as you work though the exercise you decide you prefer a value other than 65,536 for HASH_SEP, you can change it in just one place rather than in however many places you would have used a numeric literal.

However, to access HASH_SEP from the Fraction class, you will need to refer to it as “Fraction.HASH_SEP” rather than just “HASH_SEP”. A minor bit of verbosity in an otherwise concise language.

With these changes, you might bring the number of failing tests down to maybe just two or three:

JUnit version 4.12
..........E.E..Trying to divide by zero correctly triggered IllegalArgumentException: Dividing 3/2 by 0 results in an indeterminate number.
....
Time: 1.875
There were 2 failures:
1) testTo(fractions.FractionTest)
java.lang.AssertionError: expected:<[4/7, 9/14, 5/7, 11/14, 6/7, 13/14, 1, 15/14, 8/7, 17/14, 9/7, 19/14, 10/7, 3/2]> but was:<[4/7]>
2) testCompareTo(fractions.FractionTest)
java.lang.AssertionError: The test case is a prototype
FAILURES!!!
Tests run: 17, Failures: 2

If you need help getting testCompareTo() to pass, my article on comparable numeric data types from March might be of help, even though it details a Java implementation. As for testTo(), I plan to write an article about it next week.

I don’t entirely like that to() returns a mutable collection. When I figure out what kind of immutable collection to() should return, I will change to() and testTo() accordingly. And I’ll have to remember to remove the java.util.ArrayList import.

In conclusion

I hope you have found this useful. Or at least I hope it gives you a renewed appreciation for all the things your IDE does to make TDD using JUnit a breeze.

--

--

Alonso Del Arte

is a Java and Scala developer from Detroit, Michigan. AWS Cloud Practitioner Foundational certified