I'm taking an entry-level Java course and have run into an issue that is preventing me from submitting an assignment.
I have to use assertThat in my test cases to satisfy the automatic grader's requirement that I write unit tests. The issue is that I am unable to use the method without receiving this error: "The method assertThat(Point) is undefined for the type CleverBrainTest"
In Eclipse, the error shows up as a red lightbulb to the left of every line where I try to use assertThat. The error also shows up in the testing result when I attempt to run the test.
Eclipse suggests that I use assertTrue instead, and this works. However, the automatic grading system for my class rejects it. It will only accept assertThat.
Additional context:
I'm including my test case titled CleverBrainTest in the post. Please bear with me as I am very new to Java. Any guidance is greatly appreciated, and I can supply more information if needed. I'm very interested in learning why this is happening so I can address similar issues in the future. Below is the code, I'll also include the trace for the error.
// -------------------------------------------------------------------------
import student.*;
import student.tetris.*;
import static org.assertj.core.api.Assertions.*;
/**
* Tests to measure performance of CleverBrain
*
* @author My Name
* @version Today's Date
*/
public class CleverBrainTest
extends TestCase
{
//~ Fields ................................................................
//~ Constructors ..........................................................
//~Public Methods ........................................................
/**
* Tests brain's ability to place sticks in deep holes
*/
public void testStickInDeepHole()
{
Board deepHole = new Board(10, 24,
"######### ",
"######### ",
"######### ",
"######### "
);
Brain myBrain = new CleverBrain();
Piece stick = Piece.getPiece(Piece.STICK, 0);
Move best = myBrain.bestMove(deepHole, stick, 20);
// Now call the brain
best = myBrain.bestMove(deepHole, stick, 20);
// Expect the piece will go to the bottom right hole
this.assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
// Expect the piece is rotated counter-clockwise 0 times
this.assertThat(best.getPiece()).isEqualTo(Piece.SQUARE, 0); // make sure it's correct
}
/**
* Tests Brain's ability to choose a reasonable target
*/
public void testSetTarget()
{
Board squareHole = new Board(10, 24,
" ",
"##### ###",
"##### ###",
"##########"
);
Brain myBrain = new CleverBrain();
Piece square = Piece.getPiece(Piece.SQUARE, 0);
Move best = myBrain.bestMove(squareHole, square, 20);
// Now call the brain
best = myBrain.bestMove(squareHole, square, 20);
// Expect the lower left destination is where the hole is
System.out.println(best.getLocation());
this.assertThat(best.getLocation()).isEqualTo(new Point(5, 1));
}
}
The trace for the error
java.lang.Error: Unresolved compilation problem:
The method assertThat(Point) is undefined for the type CleverBrainTest
at CleverBrainTest.testSetTarget(CleverBrainTest.java:66)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Things I Have Tried
In Java, this
refers the to the instance of the enclosing class which the method was invoked on. For example, if you have the following:
public class Person {
private final String name;
public Person(String name) {
// 'this' is differentiating between the 'name' *field*
// and the 'name' *parameter*
this.name = name;
}
public void speak() {
// Note the only 'name' in scope here is the field, so
// technically 'this` can be omitted (and typically is)
System.out.println("Hello, from " + this.name + "!");
}
public static void main(String[] args) {
Person p1 = new Person("John");
Person p2 = new Person("Jane");
p1.speak();
p2.speak();
}
}
You would see the following output:
Hello, from John!
Hello, from Jane!
Because:
this == p1
for the p1.speak()
invocation.
this == p2
for the p2.speak()
invocation.
Note that this
cannot be used in static contexts (e.g., the main
method above) because there is no "current instance" in static contexts.
By using:
this.assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
You are explicitly telling Java to invoke an assertThat
method on this
, where this
is an instance of CleverBrainTest
in this context. But that class does not have an assertThat
method, thus the code fails to compile. The assertThat
method comes from AssertJ's Assertions
class. It is also a static method, meaning you do not need an instance of Assertions
to call it.
One way to fix this is to import org.assertj.core.api.Assertions
and then use:
Assertions.assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
However, you already have the following import:
import static org.assertj.core.api.Assertions.*;
That is a static import. Static imports let you reference static members (e.g., methods, enum constants, etc.) without having to prefix them with the class name. That import is also a star import, which means every static member of Assertions
is being imported. All that means you can simply do:
assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
Without the Assertions
prefix and it will still work. Though note if CleverBrainTest
did have an assertThat
method then that method would take precedence over the statically imported assertThat
method, so in that case you would have to prefix the method call with Assertions
in order to call the correct one.
Eclipse suggests that I use assertTrue instead, and this works.
There is no assertTrue
method in the code you provided, so I can only assume it comes from the TestCase
superclass (which I believe is a JUnit 3 class?).