根据Play's documentation,(MVC)模型应如下所示:
object MyModel {
//code
}
你如何对此进行单元测试?在Play's unit testing documentation中,示例模型不再被定义为对象,而是定义为类。我已经构建了我的应用程序,将模型声明为对象,这是否意味着我现在必须改变它?
这是控制器对象如何进行单元测试的示例。这样:
object MyController extends Controller {
}
必须改为:
trait MyController {
//code
}
object MyController extends Controller with MyController
为了使其可以进行单元测试,在这种情况下,单元测试看起来像这样:
object MyControllerSpec extends PlaySpecification with Results {
class TestController() extends Controller with MyController
//unit test code
}
我必须/我可以应用相同的技术来测试我的模型(对象)吗?如果是这样呢?如果不是那么唯一的方法是将所有模型作为类而不是对象?
Play Framework 2.2.1
答案 0 :(得分:1)
如果你想测试对象并且那些对象本身决定它们的依赖关系以及如何与它们交谈,唯一的方法是以某种方式替换这些依赖关系,所以例如对于数据库访问它可能提供不同的配置,对另一个数据库运行,这将要求您确保在测试运行之间保持该数据库是干净的,并且不会在测试用例之间泄漏数据。它的另一个问题是它可能会使你的测试运行缓慢。
如果您更愿意运行仅测试一段特定代码的单元测试,那么使用依赖项注入的方法有很多变化。简单依赖注入的一个例子是(关于你用控制器描述的内容):
class EntityDAO(db: SomeWayToTalkToADB) {
... defs using db ...
}
object EntityDao extends EntityDAO(Somwehere.concreteDBaccess)
然后在测试中:
"My entity dao" should {
"do stuff with the db" in {
val dao = new EntityDao(somefakeDB)
dao.doStuff mustEqual something
}
}
通过这种方式,您可以轻松提供虚假实现,例如使用mockito等创建的模拟。
其他选项可以是在第二个参数列表中为每个需要它的方法提供实际的db访问对象,可能是隐式的,以避免重复自己。你也可以使用蛋糕模式,一些DI库或可能的monad,这取决于你想要进入功能的深度。