Как заказать @ перед методами - PullRequest
3 голосов
/ 02 ноября 2011

У меня есть черта, которая добавляет пару тестов и перед блоками.Блоки @Before конкретного экземпляра запускаются раньше, чем в признаке.К сожалению, это означает, что я не могу усечь таблицы базы данных, а затем вставить фиксаторы:

trait DatabaseTest {
  @Before
  def truncate() {
    // "TRUNCATE %s".format(tableName)
  }

  def tableName
}

class PersonasTest extends DatabaseTest {
  @Before
  def addPersona() {
    // "INSERT INTO %s VALUES (...)".format(tableName)
  }


  @Test
  def testRejectsInsertWhenAlreadyInTable() {
    // "INSERT INTO %s VALUES (...)".format(tableName)
  }

  def tableName = "personas"
}

testRejectsInsertWhenAlreadyInTable всегда будет успешным, поскольку порядок выполнения будет:

  • addPersona
  • truncate
  • testRejectsInsertWhenAlreadyInTable

Каким будет правильный способ упорядочения блоков @Before без наложения слишком большого числа ограничений на подклассы?Я всегда мог объявить truncate в признаке, затем иметь метод @Before в подклассе, но затем я должен помнить, чтобы все мои подклассы вызывали этот метод усечения.

Использование JUnit 4.10 в Scala 2.9.0.1. * * тысяча двадцать-один

Ответы [ 2 ]

4 голосов
/ 03 ноября 2011

Правильный способ сделать это - использовать @Rule, расширить @ExternalResource для поведения типов до и после (в синтаксисе Java):

@Rule
public ExternalResource resource= new ExternalResource() {
        @Override
        protected void before() throws Throwable {
                myServer.connect();
        };

        @Override
        protected void after() {
                myServer.disconnect();
        };
};

Вы можете упорядочить и упорядочить несколько @Rule вместе по порядку, используя @RuleChain (введено в 4.10), снова в синтаксисе Java:

@Rule
public TestRule chain= RuleChain
                       .outerRule(new LoggingRule("outer rule")
                       .around(new LoggingRule("middle rule")
                       .around(new LoggingRule("inner rule");

Есть оговорка. Вы не можете указать открытое поле в scala (общедоступные поля оборачиваются методами доступа, а сами поля становятся закрытыми). JUnit проверяет, что @Rule применяется к открытому полю. Исправление для изменения кода JUnit, чтобы вы могли применять @Rule к методам и полям.

Это было исправлено (мной) и было объединено с master, но, к сожалению, оно еще не выпущено: оно будет частью 4.11. Таким образом, у вас есть два варианта: использовать 4.11-SNAPSHOT или загрузить версию 4.10 и применить патч для @ Rule .

Scala-код может выглядеть примерно так:

trait DatabaseTest {
    def truncate(): TestRule = {
        new ExternalResource() {
            override def before() = {
                // "TRUNCATE %s".format(tableName)
            }
        }
    }

    def extra(): TestRule = {
        // return a no-op rule
    }

    @Rule def testRule() = new RuleChain(truncate(), extra())
    def tableName
}

class PersonasTest extends DatabaseTest {
  def extra(): TestRule {
        new ExternalResource() {
            override def before() = {
                // "INSERT INTO %s VALUES (...)".format(tableName)
            }
        }
  }

  @Test
  def testRejectsInsertWhenAlreadyInTable() {
    // "INSERT INTO %s VALUES (...)".format(tableName)
  }

  def tableName = "personas"
}
0 голосов
/ 03 ноября 2011

Как насчет:

abstract class DatabaseTest {

  // "TRUNCATE %s".format(tableName)

  def tableName
}

class PersonasTest extends DatabaseTest {
  @Before
  def addPersona() {
    // "INSERT INTO %s VALUES (...)".format(tableName)
  }

  @Test
  def testRejectsInsertWhenAlreadyInTable() {
    // "INSERT INTO %s VALUES (...)".format(tableName)
  }

  def tableName = "personas"
}

В конце концов, PersonasTest is-a DatabaseTest.

...