The*_*rav 7 unit-testing scala playframework-2.0
假设我有一个控制器,其动作可以接收两个参数.
它调用两个服务,每个参数一个,服务都返回字符串
每个字符串都作为参数传递给模板
结果传递给Ok并返回.
我想编写一个简单的单元测试来确保:1 - 使用正确的参数调用正确的服务2 - 来自服务的返回值被传递给模板的正确属性
最好的方法是什么?
使用 Mockito 和 Specs2,我模拟服务来验证它们的方法调用。
我的控制器是由 Spring 实例化的。这让我可以将它视为 aclass而不是object。=> 这对于使其可controller测试至关重要。这里有一个例子:
@Controller
class MyController @Autowired()(val myServices: MyServices) extends Controller
Run Code Online (Sandbox Code Playgroud)
要为控制器启用 Spring,您必须定义一个Global对象,例如 Play! 文档解释:
object Global extends GlobalSettings {
val context = new ClassPathXmlApplicationContext("application-context.xml")
override def getControllerInstance[A](controllerClass: Class[A]): A = {
context.getBean(controllerClass)
}
}
Run Code Online (Sandbox Code Playgroud)
我的单元测试不需要Spring;我只是将协作者(模拟)传递给构造函数。
但是,对于呈现的模板,我仅测试结果的类型(Ok、BadRequest、重定向等...)。事实上,我注意到让我的测试详细扫描整个渲染模板(发送给它的参数等)并不容易,仅进行单元测试。
因此,为了断言使用正确的参数调用正确的模板,我相信运行 Selenium 的验收测试或可能的功能测试(如果您愿意)可以扫描整个预期结果。
2 - 服务的返回值被传递到模板的正确属性
检查这一点非常容易..如何?通过信任编译器!更喜欢将一些自定义类型传递给模板,而不是简单的基元,例如:
phone: String 会变成:phone: Phone。(一个简单的值对象)。因此,不必担心以非预期顺序将属性传递给模板(在单元测试或实际生产代码中)。编译器确实会警告。
这是我使用specs2进行单元测试(简化)的一个示例:(您会注意到包装器的使用:)WithFreshMocks。这case class将允许在测试后刷新所有变量(在本例中为模拟)测试。因此这是重置模拟的好方法。
class MyControllerSpec extends Specification with Mockito {
def is =
"listAllCars should retrieve all cars" ! WithFreshMocks().listAllCarsShouldRetrieveAllCars
case class WithFreshMocks() {
val myServicesMock = mock[MyServices]
val myController = new MyController(myServicesMock)
def listAllCarsShouldRetrieveAllCars = {
val FakeGetRequest = FakeRequest() //fakeRequest needed by controller
mockListAllCarsAsReturningSomeCars()
val result = myController.listAllCars(FakeGetRequest).asInstanceOf[PlainResult] //passing fakeRequest to simulate a true request
assertOkResult(result).
and(there was one(myServicesMock).listAllCars()) //verify that there is one and only one call of listAllCars. If listAllCars would take any parameters that you expected to be called, you could have precise them.
}
private def mockListAllCarsAsReturningSomeCars() {
myServicesMock.listAllCars() returns List[Cars](Car("ferrari"), Car("porsche"))
}
private def assertOkResult(result: PlainResult) = result.header.status must_== 200
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3985 次 |
| 最近记录: |