首页 文章

在scalatest中导入隐式方法

提问于
浏览
0

我正在努力理解为什么隐式导入不能像我期望的那样工作 . 简化的失败示例(使用spark,但我也可以使用我的自定义类失败)如下:

class FailingSpec extends FlatSpec with Matchers with MySparkContext {

    val testSqlctx = sqlctx
    import sqlctx.implicits._

    "sql context implicts" should "work" in {
        val failingDf = Seq(ID(1)).toDS.toDF
    }
}

MySparkContext特性在 beforeAllafterAll 中创建并销毁火花上下文,并使 sqlctx 可用(已经必须将其重新分配给局部变量以便导入含义是一个难题,但可能在不同的时间) . 然后 .toDS.toDF 是从 sqlctx.implicits 导入的隐式方法 . 运行测试结果 java.lang.NullPointerException .

如果我将导入移动到测试块的工作:

class WorkingSpec extends FlatSpec with Matchers with MySparkContext {

    "sql context implicts" should "work" in {      
        val testSqlctx = sqlctx
        import sqlctx.implicits._

        val workingDf = Seq(ID(1)).toDS.toDF
    }
}

任何想法为什么我不能在测试类的顶层导入implicits?

1 回答

  • 1

    beforeAll 在任何测试之前运行,但不在类的构造函数之前运行 . 第一个代码段中的操作顺序是:

    • 调用构造函数,执行 val testSqlctx = sqlctximport sqlctx.implicits._

    • beforeAll 被调用

    • 测试运行

    以及第二个代码段的操作顺序:

    • beforeAll 被调用

    • 测试运行,执行 val testSqlctx = sqlctximport sqlctx.implicits._

    假设您给 SparkContext 一个默认值( null )并在 beforeAll 初始化它,第一个操作顺序将尝试使用 sqlctx ,当它仍然是 null 时,从而导致空指针异常 .

相关问题