Scala、PlayFramework、Mockito、ExecutionContext null
Scala, PlayFramework, Mockito, ExecutionContext null
遵循这个答案:
我在我的项目中使用 Play 的 ExecutionContext。
最近需要用Mockito测试Play中的一些服务。
所以,这是它的简化版本:
import scala.concurrent.{ Future, ExecutionContext }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
case class Model(id: Int, name: String)
trait DAO {
def findAll(implicit ec: ExecutionContext): Future[List[Model]]
}
class Service(dao: DAO) {
def findAll: Future[List[Model]] = dao.findAll
}
测试:
import play.api.libs.concurrent.Execution.Implicits.defaultContext
// doesn't work when different ExecutionContext
// import scala.concurrent.ExecutionContext.Implicits.global
class FuturesTest extends PlaySpec with MockitoSugar with ScalaFutures {
"Service" should {
"return all future data" in {
val mockModel = Model(1, "name")
val mockDAO = mock[DAO]
when(mockDAO.findAll) thenReturn Future.successful(List(mockModel))
val service = new Service(mockDAO)
val futureData = service.findAll
whenReady(futureData) { data =>
data.map(_.name) must contain(mockModel.name)
}
}
}
}
注意测试中的注释,我在 Service
中调用 dao.findAll
时得到 NullPointException
。起初我认为 Mockito 无法处理 Scala 的 Futures 但我发现 ExecutionContext
是问题所在。由于我不是并发专家,有人可以解释为什么会这样吗?
万一有人在看,答案很明显...
import org.mockito.Matchers.any
..
mockDAO.findAll(any[ExecutionContext])
我不熟悉 Mockito 的工作原理,也不熟悉 Scala 的隐含函数。
当你没有通过时 any[ExecutionContext]
Scala 将用测试中的隐式填充它。
遵循这个答案:
最近需要用Mockito测试Play中的一些服务。 所以,这是它的简化版本:
import scala.concurrent.{ Future, ExecutionContext }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
case class Model(id: Int, name: String)
trait DAO {
def findAll(implicit ec: ExecutionContext): Future[List[Model]]
}
class Service(dao: DAO) {
def findAll: Future[List[Model]] = dao.findAll
}
测试:
import play.api.libs.concurrent.Execution.Implicits.defaultContext
// doesn't work when different ExecutionContext
// import scala.concurrent.ExecutionContext.Implicits.global
class FuturesTest extends PlaySpec with MockitoSugar with ScalaFutures {
"Service" should {
"return all future data" in {
val mockModel = Model(1, "name")
val mockDAO = mock[DAO]
when(mockDAO.findAll) thenReturn Future.successful(List(mockModel))
val service = new Service(mockDAO)
val futureData = service.findAll
whenReady(futureData) { data =>
data.map(_.name) must contain(mockModel.name)
}
}
}
}
注意测试中的注释,我在 Service
中调用 dao.findAll
时得到 NullPointException
。起初我认为 Mockito 无法处理 Scala 的 Futures 但我发现 ExecutionContext
是问题所在。由于我不是并发专家,有人可以解释为什么会这样吗?
万一有人在看,答案很明显...
import org.mockito.Matchers.any
..
mockDAO.findAll(any[ExecutionContext])
我不熟悉 Mockito 的工作原理,也不熟悉 Scala 的隐含函数。
当你没有通过时 any[ExecutionContext]
Scala 将用测试中的隐式填充它。