我在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
}
}
如果无法对此代码进行单元测试,是否建议使用其他替代数据访问方法?
1 回答
显然,这里没有办法使用模拟EntityManager,至少没有我能找到的 . 所以我不得不修改我的设计 .
Typesafe的Sargent建议在邮件列表上创建一个单独的数据库持久性子项目:https://groups.google.com/d/msg/play-framework/1u-_JbTIuQg/L5_9o4YCfoMJ . 我还没有走得那么远,但我确实通过定义一个单独的DAO接口找到了一个对我有用的解决方案 .
我将所有JPA代码放入DAO特征 - 所有实现都在那里 . 还有一个伴随对象来提供单例实例 . 像这样:
现在我将控制器更改为traits,并引用了未设置的DAO . 伴随对象将DAO实例设置为单例对象 . 这样可以避免对routes文件进行任何更改(无需实例化控制器) . 像这样:
因此,当应用程序运行时,所有内容都可以使用标准JPA代码轻松完成 . 但是当我想进行单元测试时,我可以像这样插入一个模拟DAO(这是使用Mockito):
也许这不是理想的方法,但它到目前为止一直在努力 . 我仍然有兴趣听到任何其他建议 .