如何将函数模拟为 return Scala 中的虚拟值?
How to mock a function to return a dummy value in scala?
object ReadUtils {
def readData(sqlContext: SQLContext, fileType: FileType.Value): List[DataFrame] = {
//some logic
}
我正在为执行函数编写测试
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
}
如何在为执行函数编写测试时将 readData 函数模拟为 return 虚拟值?目前正在调用实际函数。
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)
简单的答案是 - 你做不到。对象基本上是 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
object ReadUtils {
def readData(sqlContext: SQLContext, fileType: FileType.Value): List[DataFrame] = {
//some logic
}
我正在为执行函数编写测试
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
}
如何在为执行函数编写测试时将 readData 函数模拟为 return 虚拟值?目前正在调用实际函数。
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)
简单的答案是 - 你做不到。对象基本上是 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