简体   繁体   English

是否有可能在播放功能测试中模拟数据库连接以及如何?

[英]Is it possible to mock DB connection in play functional testing and how?

Some of my controllers rely on DB connection and structured as follows: 我的一些控制器依赖于数据库连接,结构如下:

def getAll(revId: Muid) = Action { implicit request =>
        DB.withConnection { implicit connection =>
...

I am trying to create a unit test for it with all mocked dependencies, including the connection as well. 我正在尝试使用所有模拟的依赖项为它创建单元测试,包括连接。 Now, injection of dependencies is easily done through Guice. 现在,通过Guice可以轻松地注入依赖项。 However, I am struggling to find a way to mock implicit connection. 但是,我正在努力寻找模拟隐式连接的方法。 And, eventually, the test is trying to connect to my default DB in test. 最后,测试试图连接到测试中的默认DB。

Is it even possible to mock implicits, given this situation, and how? 在这种情况下,甚至可以模仿隐含,以及如何?

UPDATE UPDATE

So, after playing with this thing for a while, I got the following: My class under test: 所以,在玩了这个东西一段时间之后,我得到了以下内容:我的课程正在测试中:

class ChecklistCreationScheduler @Inject()(jobScheduler: JobScheduler,
                                           dBApi: DBApi,
                                           futureChecklistRepository: FutureChecklistRepository) extends ClassLogger{
def scheduleSingleFutureChecklistJob(futureChecklistId: Muid): Unit = {
    logger.info(s"Preparing to schedule one time future checklist job for future checklist id '${futureChecklistId.uuid}'")
    val db = dBApi.database("default")
    logger.info("Database" + db)
    db.withConnection { implicit connection =>
      logger.info("Connection" + connection)
      ...
    }
}
}

And the test: 而且测试:

"ChecklistCreationScheduler#scheduleSingleFutureChecklistJob" should {
      "schedule a single job through a scheduler" in {
        val futureChecklistId = Muid.random()

        val jobScheduler = mock[JobScheduler]

        val connection = mock[Connection]
        val DB = mock[Database]
        DB.getConnection returns connection

        val dbApi = mock[DBApi]
        when(dbApi.database("default")).thenReturn(DB)

        val futureChecklistRepository = mock[FutureChecklistRepository]
        doReturn(Option.empty).when(futureChecklistRepository).getById(futureChecklistId)(connection)

        val chCreationScheduler = new ChecklistCreationScheduler(jobScheduler, dbApi, futureChecklistRepository)

        chCreationScheduler.scheduleSingleFutureChecklistJob(futureChecklistId) must throwA[UnexpectedException]
      }
    }

When I execute the test, it seems like the execution does not even get into the block of withConnection . 当我执行测试时,似乎执行甚至没有进入withConnection块。 (I am never getting to this line: logger.info("Connection" + connection) ). (我永远不会到达这一行: logger.info("Connection" + connection) )。

Any idea? 任何的想法?

Here is how you can use Dependency Injection to easily mock the database call: 以下是如何使用依赖注入轻松模拟数据库调用:

Considering this is your controller: 考虑到这是你的控制器:

package controllers

import javax.inject.Inject

import play.api._
import play.api.db.Database
import play.api.mvc._

class Application @Inject() (database: Database) extends Controller {

  def index = Action { implicit request =>
    database.withConnection { implicit  connection =>
      ???
    }
    Ok(views.html.index("Your new application is ready."))
  }
}

You can write a Specification like this : 您可以编写如下规范

import java.sql.Connection

import controllers.Application
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import org.specs2.mock._
import play.api.db.Database
import play.api.mvc.RequestHeader

@RunWith(classOf[JUnitRunner])
class ApplicationSpec extends Specification with Mockito {

  "Application" should {

    "index page" in {
      val connection = mock[Connection]
      val database = mock[Database]
      database.getConnection returns connection

      val controller = new Application(database)

      // You will also need to mock the request
      // so that you can add the expected behavior 
      val request = mock[RequestHeader]
      val result = controller.index(request)

      // do some assert about your result
      result must not beNull
    }
  }
}

Of course, some other mocks may be necessary to handle your (whole) use case. 当然,可能需要一些其他的模拟来处理你的(整个)用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Play2和ReactiveMongo测试问题:测试失败后立即进行数据库连接 - Play2 & ReactiveMongo testing issue: db connection right after test fails 如何在play框架的Module.scala中初始化一个DB连接 - How to initialize a DB connection in Module.scala in the play framework ScalaTest测试中的模拟播放JDBC连接 - Mock Play JDBC connection in ScalaTest test 如何在Scala中使用函数参数模拟方法? - How to mock a method with functional arguments in Scala? 在Play中使用JPA时使用模拟EntityManager进行单元测试 - Unit testing with a mock EntityManager when using JPA in Play 在对单元进行测试时,将模拟服务对象的依赖项注入播放控制器中 - Inject dependency of mock service object in play controller while unit testing it 如何在Scala Slick中模拟数据库 - How to mock db in Scala Slick 如何使用功能测试在Play Framework中测试控制器 - How to test a controller in Play Framework with a functional test 如何对kafka客户应用程序执行功能测试? - How to perform functional testing of a kafka consumer application? 如何在Play Framework v2中指定自定义数据库连接参数以进行测试? - How to specify custom database-connection parameters for testing purposes in Play Framework v2?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM