我正在学习入门级 Java 课程,但遇到了一个阻止我提交作业的问题。
我必须在我的测试用例中使用assertThat来满足自动评分器对我编写单元测试的要求。问题是,我无法在不收到此错误的情况下使用该方法:“方法 assertThat(Point) 对于类型 CleverBrainTest 未定义”
在 Eclipse 中,错误在我尝试使用 assertThat 的每一行的左侧显示为红色灯泡。当我尝试运行测试时,该错误也会显示在测试结果中。
Eclipse 建议我改用assertTrue,这很有效。然而,我班级的自动评分系统拒绝了它。它只会接受assertThat。
其他背景:
我在帖子中添加了名为 CleverBrainTest 的测试用例。请耐心等待,因为我对 Java 还很陌生。非常感谢任何指导,如果需要,我可以提供更多信息。我非常有兴趣了解为什么会发生这种情况,以便我将来可以解决类似的问题。下面是代码,我还将包含错误的跟踪。
// -------------------------------------------------------------------------
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));
}
}
错误追踪
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)
我尝试过的事情
在 Java 中,
this
指的是调用该方法的封闭类的实例。例如,如果您有以下情况:
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();
}
}
您将看到以下输出:
Hello, from John!
Hello, from Jane!
因为:
this == p1
用于 p1.speak()
调用。
this == p2
用于 p2.speak()
调用。
请注意,
this
不能在静态上下文中使用(例如上面的main
方法),因为静态上下文中没有“当前实例”。
通过使用:
this.assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
您明确告诉 Java 在
assertThat
上调用 this
方法,其中 this
在此上下文中是 CleverBrainTest
的实例。但该类没有 assertThat
方法,因此代码无法编译。 assertThat
方法来自AssertJ的Assertions
类。它也是一个 static 方法,这意味着您不需要 Assertions
的实例来调用它。
解决此问题的一种方法是导入
org.assertj.core.api.Assertions
然后使用:
Assertions.assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
但是,您已经导入了以下内容:
import static org.assertj.core.api.Assertions.*;
这是静态导入。静态导入允许您引用静态成员(例如,方法、枚举常量等),而无需在它们前面添加类名前缀。该导入也是星型导入,这意味着
Assertions
的每个静态成员都将被导入。所有这一切意味着您可以简单地执行以下操作:
assertThat(best.getLocation()).isEqualTo(new Point(10, 0));
没有
Assertions
前缀,它仍然可以工作。但请注意,如果 CleverBrainTest
did 有 assertThat
方法,那么该方法将优先于静态导入的 assertThat
方法,因此在这种情况下,您必须在方法调用前加上 Assertions
前缀才能调用正确的一个。