【问题标题】:Importing implicit methods in scalatest在 scalatest 中导入隐式方法
【发布时间】:2016-08-29 15:29:49
【问题描述】:

我很难理解为什么隐式导入不能像我期望的那样工作。简化的失败示例(使用 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 trait 在 beforeAllafterAll 中创建和销毁 spark 上下文,并使 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
    }
}

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

【问题讨论】:

    标签: scala implicit scalatest


    【解决方案1】:

    beforeAll 在任何测试之前运行,但不在类的构造函数之前运行。第一个sn-p中的操作顺序是:

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

    2. beforeAll 调用

    3. 测试运行

    以及第二个sn-p的操作顺序:

    1. beforeAll 调用

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

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

    【讨论】:

    • 谢谢,事后看来如此明显!所以我想我应该在 trait 的构造函数中正确初始化事物,而不是在 beforeAll 方法中。
    猜你喜欢
    • 2019-12-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    相关资源
    最近更新 更多