如何在scala中模拟函数以返回虚拟值?

kadbb459  于 2021-05-18  发布在  Spark
关注(0)|答案(1)|浏览(676)

这个问题在这里已经有答案了

模拟scala对象(4个答案)
上个月关门了。

object ReadUtils {
    def readData(sqlContext: SQLContext, fileType: FileType.Value): List[DataFrame] = {
    //some logic

}

我正在为execute函数编写测试

import com.utils.ReadUtils.readData

    class Logs extends Interface with NativeImplicits{

    override def execute(sqlContext: SQLContext){
        val inputDFs: List[DataFrame] = readData(sqlContext, FileType.PARQUET)
        //some logic
    }

在为execute函数编写测试时,如何模拟readdata函数返回一个伪值?当前它正在调用实际函数。

test("Log Test") {
val df1 = //some dummy df
val sparkSession = SparkSession
      .builder()
      .master("local[*]")
      .appName("test")
      .getOrCreate()
    sparkSession.sparkContext.setLogLevel("ERROR")

val log = new Logs()
    val mockedReadUtils = mock[ReadUtils.type]
    when(mockedReadUtils.readData(sparkSession.sqlContext,FileType.PARQUET)).thenReturn(df1)
    log.execute(sparkSession.sqlContext)
yzuktlbb

yzuktlbb1#

答案很简单-你做不到。在scala中,对象基本上是单例的,你不能模仿单例——这就是为什么他们说你应该尽量避免单例的原因之一。
您可以改为模拟sqlcontext及其在readdata函数中调用的所有函数。
作为另一种方法,您可以尝试使用某种蛋糕模式添加依赖项注入-https://medium.com/rahasak/scala-cake-pattern-e0cd894dae4e

trait DataReader {
  def readData(sqlContext: SQLContext, fileType: FileType.Value): List[DataFrame]
}

trait RealDataReader {
  def readData(sqlContext: SQLContext, fileType: FileType.Value): List[DataFrame] = {
    // some code
  }
}

trait MockedDataReader {
  def readData(sqlContext: SQLContext, fileType: FileType.Value): List[DataFrame] = {
     // some moking code
  }
}

class Logs extends Interface with NativeImplicits with DataReader {

override def execute(sqlContext: SQLContext){
  val inputDFs: List[DataFrame] = readData(sqlContext, FileType.PARQUET)
    //some logic
  }
}

class RealLogs extends Logs with RealDataReader // that would be the real class

class MockedLogs extends Logs with MockedDataReader // that would be the class for tests

相关问题