我想自动在Scala中记录单元测试名称。 org.junit.rules.TestName
的解决方案在Java中运行良好,但在Scala中运行不正常。
请考虑以下代码段:
import org.junit._
import org.junit.rules.TestName
class ScalaUnitTestExample {
@Rule val testName = new TestName
@Before def printTestCaseNameBefore() {
print("\nStart of test case " + testName.getMethodName)
}
@After def printTestCaseNameAfter() {
print("\nEnd of test case " + testName.getMethodName)
}
@Test
def checkAddition() {
Assert.assertEquals(5, 2 + 3)
}
@Test
def checkMultiplication() {
Assert.assertEquals(6, 2 * 3)
}
}
它编译得很好,但在运行时我收到以下错误消息:
There was 1 failure:
1) initializationError(ScalaUnitTestExample)
java.lang.Exception: The @Rule 'testName' must be public.
at org.junit.internal.runners.rules.RuleFieldValidator.addError(RuleFieldValidator.java:90)
(...)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
FAILURES!!!
Tests run: 1, Failures: 1
Java版本按预期工作。
我已经尝试了以下内容(根据Using JUnit @Rule with ScalaTest (e.g. TemporaryFolder)):
val _testName = new TestName
@Rule def testName = _testName
但这并没有真正帮助。在此版本中,测试用例会运行,但{testName}结果始终为{null}。
Scala中的默认访问规则是公开的,因此没有public
个关键字。另一方面,JUnit框架似乎认为它是非公开的。
有谁知道如何克服这个问题?另一个类似的解决方案也没问题!谢谢!
答案 0 :(得分:1)
如您所知,scala默认访问规则是公开的,但scala是一个技巧,该字段是私有的,它会生成getter和setter,这就是@Rule在您的代码中不起作用的原因。
您可以使用
使其正常工作import org.junit._
import org.junit.rules.TestName
class ScalaUnitTestExample {
var _testName: TestName = new TestName
@Rule
def testName = _testName
def testName_=(aTestName: TestName) {_testName = aTestName}
@Before def printTestCaseNameBefore() {
print("\nStart of test case " + testName.getMethodName)
}
@After def printTestCaseNameAfter() {
print("\nEnd of test case " + testName.getMethodName)
}
@Test
def checkAddition() {
Assert.assertEquals(5, 2 + 3)
}
@Test
def checkMultiplication() {
Assert.assertEquals(6, 2 * 3)
}
}
无论如何使用ScalaTest或Specs2会让您的生活更轻松。
答案 1 :(得分:0)
解决方案(轻松破解):将方法名称逻辑放入用Java编写的基类中。 Java源代码(UnitTestBase.java
):
import org.junit.*;
import org.junit.rules.TestName;
public class UnitTestBase {
@Rule public TestName testName = new TestName();
@Before public void printTestCaseNameBefore() {
System.out.println("Start of test case " + testName.getMethodName());
}
@After public void printTestCaseNameAfter() {
System.out.println("End of test case " + testName.getMethodName());
}
}
Scala源代码(ScalaUnitTestExample.scala
):
import org.junit._
class ScalaUnitTestExample extends UnitTestBase {
@Test
def checkAddition() {
Assert.assertEquals(5, 2 + 3)
}
@Test
def checkMultiplication() {
Assert.assertEquals(6, 2 * 3)
}
}
编译:
scalac -cp .;junit-4.9.jar UnitTestBase.java ScalaUnitTestExample.scala
执行命令
scala -cp .;junit-4.9.jar org.junit.runner.JUnitCore ScalaUnitTestExample
结果:
JUnit version 4.9
.Start of test case checkMultiplication
End of test case checkMultiplication
.Start of test case checkAddition
End of test case checkAddition
Time: 0,005
OK (2 tests)
答案 2 :(得分:0)
使用JUnit 4.12,我使用了@Jonas Anso的解决方案,并且与该版本一起使用,在4.8和4.10中不起作用。 我们必须在方法而不是字段上设置@Rule,似乎在4.8和4.10中将其忽略。 而且只需要吸气剂。