Play / Scala将Object注入控制器进行测试

时间:2016-12-22 16:30:06

标签: scala playframework-2.0 scalatest

我看到了这个帖子Play/Scala injecting controller into test我有类似的问题,但我的问题是如何注入对象来测试控制器。

控制器

@Singleton
class ExampleCtrl @Inject() (dao: TestDAO) extends Controller {
//code here
   def testMethod = Action { request =>
       dao.exampleMethod()
       Ok(Json.obj("test" -> "test")
   }
 }

DAO

class TestDAO @Inject()(protected val provider: DatabaseConfigProvider){
  def exampleMethod()
}

测试

class ExampleCtrlSpec extends PlaySpec with MockitoSugar {
  val service = mock[TestDAO]//problem on injecting DatabaseConfigProvider
  val controller = new ExampleCtrl(service)
  //service has null value for DatabaseConfigProvider properties

  "testMethod()" should {
    "return JSON" in {
      when(service.exampleMethod) thenReturn "json data"
      val result: Future[Result] =
      controller.testMethod().apply(FakeRequest())
      .withJsonBody(JSON.json("""[{"test":"test"}]"""))
      contentAsString(result) mustEqual """[{"test":"test"}]"""
    }
  }
}

2 个答案:

答案 0 :(得分:0)

所以我试图重现这个问题,但是在修复了IDE用代码识别的一些问题(例如括号丢失)之后,测试就过去了。

  

注入DatabaseConfigProvider的问题

我没有看到任何问题,因为代码正在传递。从编码器的角度来看,mock[TestDAO]实际上并没有实例化一个真实的TestDAO,但是它创建的东西看起来像一个(接口方式),但实际上并不包含任何逻辑在TestDAO内写道。因此,模拟对象也不需要注入DatabaseConfigProvider

  

service对DatabaseConfigProvider属性具有null值

因为服务(你的模拟TestDAO)是一个模拟,这不是问题,因为没有逻辑会使用它。模拟实际执行的唯一逻辑是:

when(service.exampleMethod) thenReturn "json data"

使用模拟时,您需要编写您希望它们在测试中展示的行为,就像您在上面的代码段中所做的那样。

如果您想运行任何DatabaseConfigProvider方法,可能需要:

  • 直接创建一个(例如val myProvider = [new] DatabaseConfigProvider(...)),
  • 将模拟的一个级别移出,以便您拥有一个真正的控制器,一个真实的TestDAO和一个模拟DatabaseConfigProvider(类似val controller = new ExampleCtrl(new TestDAO(mock[DatabaseConfigProvider]))),或
  • 一起写一个不同类型的测试。

答案 1 :(得分:0)

我通过以下方式解决了这个问题。

def testDAO (implicit app: Application) = {
    val app2testDAO = Application.instanceCache[TestDAO ]
    app2testDAO(app)
}
val controller = new ExampleCtrl(testDAO)