Scala / Specs2: def is (implicit ee: ExecutionEnv) = {"Служба" должна {...}} - PullRequest
0 голосов
/ 28 мая 2020

Я пытаюсь обновить проект Scala / Play до Play 2.7, Scala 2.12.11, Specs2 4.5.1.

В проекте есть следующий тест Specs2, который я не могу понять в смысле структуры спецификации Specs2 (возможно, API Specs2 сильно изменился с момента написания теста).

Когда я посмотрел на структуру спецификаций в текущем API, я не смог см. любой пример метода is в сочетании с should.

Что это должно было означать?

Как я могу переписать такую ​​спецификацию в текущем API Specs2?

Я также заметил, что тестовый код использовал import org.specs2.mutable.Specification вместо import org.specs2.Specification, который должен использоваться при использовании метода is. И он использует def is(implicit ee: ExecutionEnv) вместо def is.

Вот старый тест:

package services

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import org.specs2.specification.mutable.ExecutionEnvironment
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.test.WithApplication
import play.modules.reactivemongo._

import scala.concurrent.duration._

class StatisticsServiceSpec() extends Specification with ExecutionEnvironment {

  def is(implicit ee: ExecutionEnv) = {
    "The StatisticsService" should {

      "compute and publish statistics" in new WithApplication() {
        val repository = new MongoStatisticsRepository(configuredAppBuilder.injector.instanceOf[ReactiveMongoApi])
        val wsTwitterService = new WSTwitterService
        val service = new DefaultStatisticsService(repository, wsTwitterService)

        val f = service.createUserStatistics("elmanu")

        f must beEqualTo(()).await(retries = 0, timeout = 5.seconds)
      }

    }

    def configuredAppBuilder = {
      import scala.collection.JavaConversions.iterableAsScalaIterable

      val env = play.api.Environment.simple(mode = play.api.Mode.Test)
      val config = play.api.Configuration.load(env)
      val modules = config.getStringList("play.modules.enabled").fold(
        List.empty[String])(l => iterableAsScalaIterable(l).toList)

      new GuiceApplicationBuilder().
        configure("play.modules.enabled" -> (modules :+
          "play.modules.reactivemongo.ReactiveMongoModule")).build
    }
  }

}

Чтобы упростить код до фактического API Specs2, я думаю, что это может быть сводится к примерно так:

package services

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification

import scala.concurrent.Future
import play.api.test.WithApplication

import scala.concurrent.duration._

class StatisticsServiceSpec(implicit ee: ExecutionEnv) extends Specification /* with ExecutionEnvironment */ {

  def is(implicit ee: ExecutionEnv) = {

    "The StatisticsService" should {

      "compute and publish statistics" in new WithApplication() {

        val f = Future(1)

        f must beEqualTo(1).await(retries = 0, timeout = 5.seconds)
      }
    }
  }
}

Обратите внимание, что я удалил черту ExecutionEnvironment, поскольку, похоже, он был удален из библиотеки.

Теперь код, наконец, компилируется, но когда я пытаюсь запустить тест, ошибок нет, но на самом деле тест не запускается: результат Empty test suite.

1 Ответ

3 голосов
/ 28 мая 2020

Новая спецификация должна быть

package services

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification

import scala.concurrent.Future
import play.api.test.WithApplication

import scala.concurrent.duration._

class StatisticsServiceSpec(implicit ee: ExecutionEnv) extends Specification {
  "The StatisticsService" should {
    "compute and publish statistics" in new WithApplication() {
      val f = Future(1)
      f must beEqualTo(1).await(retries = 0, timeout = 5.seconds)
    }
  }
}

Теперь действительно предполагается, что ExecutionEnv будет извлекаться как член спецификации напрямую (с implicit, чтобы сделать его доступным для метода await ).

is не требуется в "изменяемой" спецификации. is - это функция в Specification, в которой вы объявляете все «Фрагменты» своей спецификации (Fragment - это Description + Execution). В изменяемой спецификации эта функция автоматически заполняется из-за того, что вы запускаете вызовы метода непосредственно в теле класса при создании экземпляра спецификации. Фрагменты, созданные should и in, собираются в изменяемую переменную, отсюда и название «изменяемая спецификация».

Если вы определяете def is(implicit ee: ExecutionEnv), это похоже на определение другого, действительного, is определение, о котором specs2 не знает, при этом ничего не создавая для метода def is: Fragments. Вот почему вы получаете пустую спецификацию.

...