[英]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.