【问题标题】:Unit testing with a mock EntityManager when using JPA in Play在 Play 中使用 JPA 时使用模拟 EntityManager 进行单元测试
【发布时间】:2014-02-26 22:47:05
【问题描述】:

我在 Play 中有一些 (Scala) 代码,它使用 JPA 进行数据库访问。工作正常。但我想对我的代码进行单元测试,这需要使用模拟 EntityManager。这可能吗?

我的测试是用 specs2 编写的(通过扩展 PlaySpecification)并使用 JUnit 运行。我正在使用 Mockito 来模拟 EntityManager。但我希望能够使用其他框架来做到这一点。

我的代码如下所示:

object MyThing {
    def create(...) : MyThing = {
        val newThing = ...
        JPA.withTransaction(new play.libs.F.Function0[Unit]() {
            def apply() = {
                JPA.em().persist(newThing)
            }
        })
        return newThing
    }
}

如果无法对此代码进行单元测试,是否有其他推荐的数据访问方法?

【问题讨论】:

    标签: unit-testing scala playframework playframework-2.2


    【解决方案1】:

    显然这里没有办法使用模拟 EntityManager,至少我找不到。所以我不得不修改我的设计。

    Typesafe 的 Will Sargent 建议在邮件列表中创建一个单独的 DB 持久性子项目:https://groups.google.com/d/msg/play-framework/1u-_JbTIuQg/L5_9o4YCfoMJ。我还没有走那么远,但通过定义一个单独的 DAO 接口,我确实找到了一个适合我的解决方案。

    我将所有 JPA 代码放入 DAO 特征中 - 所有实现都在其中。还有一个伴随对象来提供一个单例实例。像这样:

    trait MyThingDAO {
        def create(...) : MyThing = { ... }
    }
    object MyThingDAO extends MyThingDAO
    

    现在我将控制器更改为特征,并引用未设置的 DAO。伴随对象将 DAO 实例设置为单例对象。这避免了对路由文件进行任何更改(无需实例化控制器)。像这样:

    trait MyThingController {
        val myThingDao : MyThingDAO
        def myAction = Action { implicit request => ... }
    }
    object MyThingController {
        val myThingDao = MyThingDAO
    }
    

    因此,当应用程序运行时,一切都可以通过标准 JPA 代码轻松运行。但是当我想进行单元测试时,我可以像这样插入一个模拟 DAO(这是使用 Mockito):

    ...
    val mockDao = mock[MyThingDAO]
    val controller = new MyThingController() { val myThingDao = mockDao }
    ...
    

    也许这不是理想的方法,但到目前为止它一直有效。我仍然有兴趣听到任何其他建议。

    【讨论】:

      猜你喜欢
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多