Загрузка контекста приложения в тестах контроллера с использованием Play и scalatest (+ specs2) - PullRequest
0 голосов
/ 29 мая 2019

У меня есть приложение Play, и я пытаюсь разработать некоторые модульные тесты для моих контроллеров с использованием scalatest (также пытался использовать specs2).Я не очень разбираюсь в платформе Play.

Для тестирования я использую следующие зависимости

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

Прежде всего, я попытался разработать тесты с использованием specs2 и WithServertrait, но я не могу использовать класс PlaySpecification, хотя библиотека spec2, кажется, находится в пути к классам.Впоследствии я попытался использовать scalatest, но у меня возникают те же ошибки, независимо от того, что я пытался.

  • Я пытался использовать контроллер и вызывать метод напрямую
  • Я пытался использовать WSClientдля маршрутизации запроса
  • я пытался использовать метод маршрутизации Helpers
  • я пытался использовать пользовательский конструктор приложений и использовать это приложение для маршрутизации моего запроса
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.

Я пришел к выводу, что мне не хватает подходящей инициализации контекста приложения для моих тестов.В руководствах и официальной документации нет упоминаний об этом, даже если это необходимо, но кажется, что эта ошибка связана с этим.

Короче говоря, после всех этих часов я просто хочу протестировать свой контроллер.

После преодоления множества других ошибок эта ошибка действительно сохраняется.

Общие вопросы:

  • Почему я не могу расширить свой класс с помощью PlaySpecification, в то время как specs2в моем classpath?
  • Нужно ли загружать контекст тестового приложения для запуска тестов контроллера?
  • Является ли предпочтительным использование specs2 для масштабирования для тестирования контроллера или наоборот?
  • Существует ли базовый тестовый шаблон для контроллеров для обеих библиотек?

Пожалуйста, включите импорт и зависимости, если вы отправите код

...