使用Play和Scalatest(+ specs2)在控制器测试中加载应用程序上下文

时间:2019-05-29 11:59:14

标签: scala rest playframework scalatest

我有一个Play应用程序,我正在尝试使用scalatest(也尝试使用specs2)为我的控制器开发一些单元测试。我对Play框架不熟悉。

为了测试,我使用以下依赖项

libraryDependencies += scalatest % Test,
libraryDependencies += scalatestplus,
libraryDependencies += mockito % Test,
libraryDependencies += specs2 % Test

首先,我尝试使用specs2和WithServer特性开发测试,但是尽管spec2 lib似乎在类路径中,但我不能使用PlaySpecification类。之后,我尝试使用scalatest,但无论尝试如何,都遇到相同的错误。

  • 我尝试使用控制器并直接调用方法
  • 我尝试使用WSClient来路由请求
  • 我尝试使用辅助路线方法
  • 我尝试使用自定义应用程序构建器并使用此应用程序路由我的请求
val application = new GuiceApplicationBuilder()
                                .in(new File("unit-application.conf"))
                                .in(Mode.Test)
                                .build

play.api.test.Helpers.route(application,route)
  • 我尝试基于this
  • 测试我的控制器
  • this
  • 我尝试构建自定义应用程序加载器并创建构建器,并进一步基于该应用程序实例
class CustomApplicationLoader extends GuiceApplicationLoader {

    override def builder(context: Context): GuiceApplicationBuilder = {
        val builder = initialBuilder.in(context.environment).overrides(overrides(context): _*)
        context.environment.mode match {
            case Prod => {
                // start mode
                val prodConf = Configuration(ConfigFactory.load("prod.conf"))
                builder.loadConfig(prodConf ++ context.initialConfiguration)
            }
            case Dev => {
                Logger.error("*** Custom Loader DEV****")
                // run mode
                val devConf = Configuration(ConfigFactory.load("dev.conf"))
                builder.loadConfig(devConf ++ context.initialConfiguration)
            }
            case Test => {
                Logger.error("*** Custom Loader TEST ****")
                // test mode
                val testConf = Configuration(ConfigFactory.load("test.conf"))
                builder.loadConfig(testConf ++ context.initialConfiguration)
            }
        }
    }
}
  • 我尝试使用specs2(即使我无法使用PlaySpecification类)
WsTestClient.withClient { ws =>
                val headers = Seq("Accept" -> "application/json")
                val baseURL = "http://localhost:19001/<url>/"
                val response = Helpers.await(ws.url(baseURL)
                        .post("{\"boardId\":\"a180272f-8fb0-4485-9de4-7e374cb439f2\","\"name\":\"lala\",\"mode\":\"IN_SYNC\",\"role\":1}"), 10, TimeUnit.SECONDS)
                response.status == 200
            }

测试代码如下

class MySpec extends PlaySpec
        with MockitoSugar
        with GuiceOneServerPerSuite {


    "MyController" should {
        "create a new entry" in {

        }

            val mockCC = Helpers.stubControllerComponents()
            val mockAC = mock[AuthComponents]
            val mockSBD = mock[SlickDao]
            val mockBA = mock[BaseActionA]
            val mockGA = mock[BaseActionB]
            val mockEC = mock[ExecutionContexts]
            val body = Json.obj("id" -> "sfdasfd", "name" -> "sadfasg", "mode" -> "A")
            val headers = FakeHeaders(Seq(CONTENT_TYPE -> "applications/json"))
            val req = FakeRequest(POST,
                                                         controllers.routes.MyController.share().url,
                                                         headers,
                                                         body)

            route(app, req)
            val myController = new MyController(mockCC, mockAC, mockSBD, mockBA, mockGA, mockEC)
            // myController.share.apply(req)
        }

控制器代码如下

class MyController @Inject()(cc: ControllerComponents,authComponents: AuthComponents,   myDao: MyDao,baseActionA: BaseActionA,baseActionB: BaseActionB,contexts: ExecutionContexts) extends AbstractController(cc) {

    val logger = Logger(this.getClass)


    def share: Action[JsValue] = (authComponents.securedAction) (parse.json) { implicit request: securedRequest[JsValue] =>
        Json.fromJson[MyIncomingRequest](request.body) match {
}
}
}

我的测试应用程序配置如下

# disable evolutions (creating an application / injector using GuiceApplicationBuilder would
# implicitly apply the evolutions
play.evolutions.enabled = false

# database configuration properties

# allow or disallow tests to modify a non-localhost database
testing.allowNonLocalDb = false


# Modules
play.modules.enabled += "modules.SilhouetteModule"
play.modules.enabled += "modules.SAMLModule"
play.modules.enabled += "modules.AuthModule"
play.modules.enabled += "modules.Module"

所有上述动作都会导致相同的结果。我有以下70个错误

xx) No implementation for <name_of_class> was bound.

我已经在这里发挥了作用,但是我认为我缺少针对测试的应用程序上下文的适当初始化。在教程和官方文档中,甚至没有提到这一点,甚至仍然有必要指出此错误。

简而言之,在所有这些小时之后,我只想测试我的控制器。

克服了许多其他错误之后,这才是真正存在的错误。

总体问题:

  • 为什么当specs2在类路径中时,我不能使用PlaySpecification扩展我的课程吗?
  • 我是否必须加载测试应用程序上下文才能运行控制器测试?
  • 是否最好使用specs2对控制器测试进行标测,反之亦然?
  • 是否有针对两个库的控制器的基本测试模式?

如果发布代码,请包括导入和依赖项

0 个答案:

没有答案