在创建规范期间引发了异常:null

时间:2016-02-02 11:53:08

标签: scala apache-spark specs2

我正在尝试使用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循环将输出转换为String,并将其与correctOutput String进行比较。

当我尝试执行此测试时,我收到以下异常:

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的方法?

2 个答案:

答案 0 :(得分:2)

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

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

在实例化类时执行此代码。因此,如果任何表达式抛出异常,则类实例化将失败,并且specs2将无法报告有关您的规范结构的任何内容。您通常可以使用lazy val代替val s:

来阻止这种情况
class MyClass {
  lazy val arr = Array(Array("1", "2", "3"), Array("4","5","6"))
  lazy val rdd = sc.parallelize(arr)
}

答案 1 :(得分:0)

解决了。问题在于

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
     }
  }

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