将 scalatest 与 before/after 一起使用时如何避免 'null'?
How to avoid 'null' when use scalatest with before/after?
从这个article about spark testing,有一些示例代码:
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()
}
}
(...)
它有效,但有一个可为 null 的变量 sc
。这里很合理,但我还是想避免。
我尝试使用:
private var sc: Option[SparkContext] = None
before {
sc = Some(new SparkContext(conf))
}
after {
sc.foreach(_.stop())
}
(...)
但问题是,我必须在测试中使用sc
作为Option[SparkContext]
,这不像普通的那样方便SparkContext
有没有办法让测试继续工作,但我们可以使用 val sc: SparkContext
?
(我知道在 specs2 中可以,但不知道如何在 scalatest 中实现,我们现在必须使用 scalatest)
您可以放弃使用 before
,而只使用 lazy 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()
}
}
}
那么在你的测试中你只需使用 'withSpark':
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 而不是 Scalatest,设计截然不同而且更好,抱歉你不能切换。
从这个article about spark testing,有一些示例代码:
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()
}
}
(...)
它有效,但有一个可为 null 的变量 sc
。这里很合理,但我还是想避免。
我尝试使用:
private var sc: Option[SparkContext] = None
before {
sc = Some(new SparkContext(conf))
}
after {
sc.foreach(_.stop())
}
(...)
但问题是,我必须在测试中使用sc
作为Option[SparkContext]
,这不像普通的那样方便SparkContext
有没有办法让测试继续工作,但我们可以使用 val sc: SparkContext
?
(我知道在 specs2 中可以,但不知道如何在 scalatest 中实现,我们现在必须使用 scalatest)
您可以放弃使用 before
,而只使用 lazy 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()
}
}
}
那么在你的测试中你只需使用 'withSpark':
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 而不是 Scalatest,设计截然不同而且更好,抱歉你不能切换。