创建规范时出现异常:null

An exception was raised during the creation of the specification: null

我正在尝试制作一个测试用例来测试使用 specs2 的函数。

"Case 8: getHistograms" should {
    val correctOutput = "(2.0,3.0,4.0,5.0)(1,0,1),(3.0,4.0,5.0,6.0)(1,0,1),"
    val arr = Array(Array("1", "2", "3"), Array("4","5","6"))
    val rdd = sc.parallelize(arr) 
    val header = Array("a","b","c")
    val skipCols = Array(0,1)
    val nBins = 3

      "return with correct output" in {
         val output = Util.getHistograms(rdd, header, skipCols, nBins)
         var str = ""
         for(i <-0 until output._1.length){
            str += "("+output._1(i).mkString(",")+")"+"("+output._2(i).mkString(",")+"),"
         }

        str must_== correctOutput
     }
  }

getHistogram 方法返回此格式的输出:

(ArrayBuffer[Array[Double]], ArrayBuffer[Array[Long]])

for 循环正在将输出转换为字符串并与 correctOutput 字符串进行比较。

当我尝试执行此测试时出现以下异常:

org.specs2.specification.dsl.mutable.SpecificationCreationException: 
An exception was raised during the creation of the specification: null.
This means that you have some code which should be enclosed in an example. Instead of writing:

 "this is a block of examples" in {
   // set-up something
   createDatabase
   "first example" in { 1 must_== 1 }
   "second example" in { 1 must_== 1 }
 }

You should write:

 "this is a block of examples" in {
   "the setup must be ok" in {
     createDatabase must not(throwAn[Exception])
   }
   "first example" in { 1 must_== 1 }
   "second example" in { 1 must_== 1 }
 }

 Be careful because in the specification above the expectation might be that the
 database will be created before the "first" and "second" examples. This will NOT be the case
 unless you mark the specification as `sequential`. You can also have a look at the `BeforeEach/BeforeAll` traits
 to implement this kind of functionality.

我正在使用相同的语法测试其他方法,它们运行良好。我无法理解为什么仅使用此方法会发生此异常。请帮忙。

更新:发现它的发生是因为 sc.parallelize(arr)。有人可以解释为什么会引发此异常吗?有什么方法可以测试将 RDD 作为参数的方法吗?

解决了。问题是

val rdd = sc.parallelize(arr) 

应该是写在里面的块里面。

正确代码:

"Case 8: getHistograms" should {
    val correctOutput = "(2.0,3.0,4.0,5.0)(1,0,1),(3.0,4.0,5.0,6.0)(1,0,1),"
    val arr = Array(Array("1", "2", "3"), Array("4","5","6")) 
    val header = Array("a","b","c")
    val skipCols = Array(0,1)
    val nBins = 3

      "return with correct output" in {
         val rdd = sc.parallelize(arr)
         val output = Util.getHistograms(rdd, header, skipCols, nBins)
         var str = ""
         for(i <-0 until output._1.length){
            str += "("+output._1(i).mkString(",")+")"+"("+output._2(i).mkString(",")+"),"
         }

        str must_== correctOutput
     }
  }

我还是不知道为什么会这样。如果有人能提供帮助,将不胜感激。

在 Scala 中,当您创建 class 时,您可以向 class 主体添加任意代码,例如 vals:

class MyClass {
  val a = { sys.error("boom"); 1 }
}

此代码在 class 实例化时执行。因此,如果任何表达式抛出异常,class 实例化将失败,并且 specs2 将无法报告有关您的规范结构的任何信息。您通常可以通过使用 lazy vals 而不是 vals 来防止这种情况:

class MyClass {
  lazy val arr = Array(Array("1", "2", "3"), Array("4","5","6"))
  lazy val rdd = sc.parallelize(arr)
}