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:
- The class instructed me to set up my test classes as JUnit 3 tests, which I have done.
- I'm also supposed to include certain imports at the top of the test class, which I think I have done properly.
- CleverBrain implements the Brain interface, which is an interface for a bot that automatically plays Tetris based on student-written methods. This is my first time trying to write tests for an interface. I suspect that's why I'm running into issues. I may just not understand how to do this properly.
- For some reason, when I tried making a setUp() method, it did not work. I instead had to boilerplate all my initial setup for my tests in each method. I have not run into this issue in the past, and I wonder if it has something to do with writing tests for interfaces.
- I'm using a Ubuntu-based Linux distribution
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
- Including the jar (or at least what I believe to be the correct jar -- it's called assertj-core-3.19.0.jar) for assertJ in the project's build path. Strangely enough, I haven't needed to do this to get assertions working properly in my previous projects (none of which involved working with interfaces). This did not work. The error persisted.
- Using JUnit 4. I couldn't get this to work, maybe due to user error. I'm not sure if this is a valid fix anyway because the class instructs me to use JUnit 3. This also did not resolve the error.
In Java,
thisrefers the to the instance of the enclosing class which the method was invoked on. For example, if you have the following:You would see the following output:
Because:
this == p1for thep1.speak()invocation.this == p2for thep2.speak()invocation.Note that
thiscannot be used in static contexts (e.g., themainmethod above) because there is no "current instance" in static contexts.By using:
You are explicitly telling Java to invoke an
assertThatmethod onthis, wherethisis an instance ofCleverBrainTestin this context. But that class does not have anassertThatmethod, thus the code fails to compile. TheassertThatmethod comes from AssertJ'sAssertionsclass. It is also a static method, meaning you do not need an instance ofAssertionsto call it.One way to fix this is to import
org.assertj.core.api.Assertionsand then use:However, you already have the following import:
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
Assertionsis being imported. All that means you can simply do:Without the
Assertionsprefix and it will still work. Though note ifCleverBrainTestdid have anassertThatmethod then that method would take precedence over the statically importedassertThatmethod, so in that case you would have to prefix the method call withAssertionsin order to call the correct one.There is no
assertTruemethod in the code you provided, so I can only assume it comes from theTestCasesuperclass (which I believe is a JUnit 3 class?).