Переопределение черты и самопознания - PullRequest
2 голосов
/ 03 июля 2011

Я хочу переопределить черту ScalaTest BeforeAndAfterEach, чтобы эта штука была реализована один раз для всех моих тестов. Наконец я получил его для компиляции, но я не понимаю, почему.

trait MySetup extends BeforeAndAfterEach {
  this : org.scalatest.BeforeAndAfterEach with org.scalatest.Suite =>
  var service: String = _

  abstract override def beforeEach(): Unit = {
    service = "apa"
    super.beforeEach()
  }

  abstract override def afterEach(): Unit = {
    service = ""
  }
}

То, что заставило его работать, это строка:

  this : org.scalatest.BeforeAndAfterEach with org.scalatest.Suite =>

Я нашел его в начале реализации BeforeAndAfterEach и скопировал.

Что это делает и зачем мне это нужно?

Обновление:

Это более простая версия.

trait MySetup extends FlatSpec with BeforeAndAfterEach {
  var service: String = _

  override def beforeEach {
    service = "apa"
    super.beforeEach
  }

  override def afterEach {
    service = ""
    super.afterEach
  }
}

Ответы [ 3 ]

5 голосов
/ 03 июля 2011

BeforeAndAfterEach имеет собственный тип Suite, что означает, что BeforeAndAfterEach можно смешивать только с типом, расширяющим Suite. ScalaTest хочет, чтобы вы сначала выбрали тип основного набора, а затем поведение при добавлении.

Объявление собственного типа не наследуется в под-признаках, поэтому вам нужно переопределить этот тип.

В следующем вопросе есть некоторые компромиссы между типами self и sub-traits: В чем разница между подтипами self-types и trait?

Некоторые сведения о дизайне ScalaTest см .:

http://www.artima.com/scalazine/articles/selfless_trait_pattern.html

1 голос
/ 04 июля 2011

Я бы написал MySetup следующим образом:

import org.scalatest.Suite
import org.scalatest.BeforeAndAfterEach

trait MySetup extends BeforeAndAfterEach { this: Suite =>

  var service: String = _

  abstract override def beforeEach(): Unit = {
    service = "apa"
    super.beforeEach()
  }

  abstract override def afterEach(): Unit = {

    try {
      super.afterEach() // To be stackable, must call super.afterEach
    }
    finally {
      service = ""
    }
  }
}

Таким образом, тип личности менее навязчив.Майк ответит правильно.Идея состоит в том, чтобы позволить чертам составлять стеки, так что вы можете смешивать разные черты, например, в разных порядках, если хотите.Другая релевантная статья - «Шаблон стекируемой черты»:

http://www.artima.com/scalazine/articles/stackable_trait_pattern.html

Вы также можете найти полезные примеры в соответствующем разделе Scaladoc:

http://www.scalatest.org/scaladoc-1.6.1/org/scalatest/FlatSpec.html#composingFixtures

Заметьте, я тоже называю super.afterEach.Чтобы быть наращиваемым, вам нужно вызывать super как до, так и после.Я делаю это в попытке, чтобы, если super.afterEach сработал с исключением, вы по-прежнему получаете последующее поведение этой черты.(Хотя, вероятно, ваш Suite все равно прервется в этот момент, поэтому в этом случае это, вероятно, не имеет значения. Но в целом это хорошая идея.)

0 голосов
/ 03 июля 2011

Это синтаксис Скаласа для внедрения зависимостей.

this: <dependency> =>

Это означает буквально this черта зависит от <dependency> черта. Прочитайте эту статью , чтобы узнать больше.

...