如何避免';空';何时将scalatest与before/after一起使用?

如何避免';空';何时将scalatest与before/after一起使用?,scala,null,scalatest,Scala,Null,Scalatest,在此基础上,有一些示例代码: class SparkExampleSpec extends FlatSpec with BeforeAndAfter { private val master = "local[2]" private val appName = "example-spark" private var sc: SparkContext = _ before { val conf = new SparkConf() .setMaster(ma

在此基础上,有一些示例代码:

class SparkExampleSpec extends FlatSpec with BeforeAndAfter {

  private val master = "local[2]"
  private val appName = "example-spark"

  private var sc: SparkContext = _

  before {
    val conf = new SparkConf()
      .setMaster(master)
      .setAppName(appName)

    sc = new SparkContext(conf)
  }

  after {
    if (sc != null) {
      sc.stop()
    }
  }
  (...)
它可以工作,但是有一个可为空的变量
sc
。这是合理的,但我还是想避免

我尝试使用:

private var sc: Option[SparkContext] = None

  before {
    sc = Some(new SparkContext(conf))
  }

  after {
    sc.foreach(_.stop())
  }
  (...)
但问题是,我必须在测试中使用
sc
作为
选项[SparkContext]
,这与普通的
SparkContext

有没有办法保持测试正常运行,但我们可以使用
val sc:SparkContext


(我知道这在specs2中是可能的,但不确定如何在scalatest中实现,我们现在必须使用scalatest)

您可以在
之前使用
,而只使用
惰性val
,因此在第一次测试调用它时初始化上下文:

class SparkExampleSpec extends FlatSpec with BeforeAndAfter {

  private val master = "local[2]"
  private val appName = "example-spark"

  private lazy val conf = new SparkConf()
    .setMaster(master)
    .setAppName(appName)
  private lazy val sc = new SparkContext(conf)

  after {
    sc.stop()
  }
更新:

所以我以前也遇到过类似的情况,我们最终得到了如下特征模式:

trait SparkAddOn {

  val conf:SparkConf

  def withSpark(f: SparkContext => Unit) ={
    val sc: SparkContext = new SparkContext(conf)
    try{
      f(sc)
    } finally {
      sc.stop()
    }
  }
}
那么,在测试中,您只需使用“WithPark”:

class SparkExampleSpec extends FlatSpec with SparkAddOn {

  private val master = "local[2]"
  private val appName = "example-spark"

  val conf = new SparkConf()
    .setMaster(master)
    .setAppName(appName)

  "test" should "do something" in withSpark { sc =>

  }
}

最后,我要说的是,我更喜欢Specs2而不是ScalateTest,它的设计与ScalateTest完全不同,更好的是,很抱歉您不能切换。

但是可能会有多个测试,
sc
在更新解决方案之前,如果不在
内,则只会初始化一次,试一试,让我知道它是否适合您我们最终得到了相同的解决方案:)