是否可以模拟在另一个函数中定义的函数?

时间:2014-11-03 17:09:42

标签: scala scalatest scalamock

我有一些访问数据库的函数,我需要为测试目的进行模拟。

为了便于使用,我想在另一个函数中定义这些函数,我可以利用scope来减少我必须传递的参数数量。

我需要测试父函数,同时模拟嵌套函数。

是否存在模拟嵌套函数的技巧?

作为第二个问题,有嵌套在任意深度时模拟函数的方法吗?

还有一个注意事项:我的项目很轻,我甚至没有使用经典的嘲讽,只有像stackable traits那样this blog post建议;但对于这个问题,任何一种嘲弄都没问题。

以下是一些非常简单的示例代码:

class Storage {
  def storeData(specId: Long, data: String): Unit = {
    val rawPath = "/path/to/file"

    def storeFsEntry: Unit = {
      // do stuff
    }

    def storeDbEntry: Unit = {
      // do stuff we need mocked
    }

    if ( specId == 1 )
    {
      storeDbEntry
      storeFsEntry
    }
  }
}

1 个答案:

答案 0 :(得分:0)

这是不可能的,但你可以定义一个特性并在你的函数中实现它(如果你真的希望这个逻辑在里面实现):

class Storage {

    trait Storing {
         def path: String //you have to define all free members
         def storeDbEntry: Unit
         def storeFsEntry: Unit
    }

    def storeData(specId: Long, data: String, storingDefault: Option[Storing] = None): Unit = {

       val myStoring = new Storing {
          ...implement it here
       }

       val storing = storingDefault getOrElse myStoring 
       import storing._

       if ( specId == 1 ) {
           storeDbEntry
           storeFsEntry
       }
    }
}

你的模拟将是这样的:

trait StorageMock extends Storage {

    override def storeData(specId: Long, data: String, storingDefault: Option[Storing] = None): Unit = {
        val storingOverride = new Storing { ... } //mocking functionality    
        super.storeData(specId, data, storingDefault orElse Some(storingOverride))
    }

}

new Storage with StorageMock

您也可以将storedDefault转换为成员而不是函数参数。

为内部函数执行相同操作的原因是它们是私有的,并且无法对它们执行类型检查(与内部特征相比)。