Как работает Junit @Rule?

195

Я хочу написать контрольные примеры для большей части кода, я хотел бы узнать подробности о @Ruleфункции аннотации JUnit , чтобы я мог использовать ее для написания контрольных примеров. Пожалуйста, предоставьте несколько хороших ответов или ссылок, которые дают простое описание его функциональности на простом примере.

Дипак
источник
я уже прошел по этой ссылке http://cwd.dhemery.com/2011/01/what-junit-rules-are-good-for/
Дипак
Я нашел, что эта статья объясняет это @Ruleдовольно хорошо, особенно ознакомьтесь с последним разделом «Последовательность событий в деталях»
Петер Перхач
Я думаю, что это похоже на концепцию инъекции, я прав?
Чао
Спасибо, что поделились этой ссылкой. Одно неясно. Когда вызывается DEFAULT Statement.evaluate ()? Вызывается ли он перед методом оценки () всех правил или после всех них? Я думаю, после всех из них.
MasterJoe2
@ testerjoe2 вы можете полностью игнорировать заявление по умолчанию. Вы можете делегировать его или просто заменить его каким-либо другим собственным Заявлением. Это не называется , вы можете позвонить или нет. Это было в пункте 10: «Метод оценки () в операторе скриншота вызывает метод оценки () оператора по умолчанию».
Петер Перхач

Ответы:

156

Правила используются для добавления дополнительной функциональности, которая применяется ко всем тестам в классе теста, но в более общем виде.

Например, ExternalResource выполняет код до и после тестового метода, без использования @Beforeи @After. Использование ExternalResourceвместо @Beforeи @Afterдает возможности для лучшего повторного использования кода; одно и то же правило можно использовать из двух разных тестовых классов.

Дизайн был основан на: Перехватчики в JUnit

Для получения дополнительной информации см. JUnit wiki: Rules .

Мэтью Фарвелл
источник
1
Исправление: «Например, ExternalResource выполняет код до и после тестового класса ». Есть кое-что об использовании apply () для запуска ExternalResource между тестами.
derekm
62

Правила Junit работают по принципу АОП (аспектно-ориентированное программирование). Он перехватывает тестовый метод, таким образом предоставляя возможность сделать некоторые вещи до или после выполнения определенного тестового метода.

Возьмите пример кода ниже:

public class JunitRuleTest {

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  @Test
  public void testRule() throws IOException {
    File newFolder = tempFolder.newFolder("Temp Folder");
    assertTrue(newFolder.exists());
  }
} 

Каждый раз, когда выполняется вышеуказанный метод тестирования, создается временная папка, которая удаляется после выполнения метода. Это пример стандартного правила, предоставленного Junit.

Подобное поведение также может быть достигнуто путем создания наших собственных правил. Junit предоставляет интерфейс TestRule, который может быть реализован для создания нашего собственного правила Junit.

Вот полезная ссылка для справки:

Абхишек Моханти
источник
4
поэтому он удаляется без написания кода для удаления / очистки объекта?
Дрор
посмотрите на источник github.com/junit-team/junit4/blob/master/src/main/java/org/… , папка создается в методе обратного вызова before () и удаляется в методе обратного вызова after (). ..
Пьерлуиджи Вернетто
1
Для людей, которые могут не понимать, почему TemporaryFolder удаляется, это потому, что это TemporaryFolder, предоставленный Junit, чтобы служить временной папкой, которая автоматически удаляется - т.е. шаг разрыва является частью самого класса TemporaryFolder.
Миндаугас Бернатавичюс
18

Объяснение того, как это работает:

JUnit оборачивает ваш тестовый метод в объект Statement, так и Execute()выполняет ваш тест. Затем вместо statement.Execute()прямого вызова для запуска теста JUnit передает инструкцию в TestRule с @Ruleаннотацией. Функция «применения» TestRule возвращает новый оператор, заданный оператором с вашим тестом. Новый Execute()метод Statement может вызывать метод execute тестового Statement (или нет, или вызывать его несколько раз) и делать все, что захочет before and after.

Теперь у JUnit есть новый оператор, который делает больше, чем просто запускает тест, и он может снова передать его другим правилам, прежде чем, наконец, вызвать Execute.

Александр Тейлор
источник
2
Оператор имеет метод оценки, а не выполнения.
Hemanth
0

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

Например, используя правило @Timeout, мы можем установить время ожидания для всех тестов.

public class TestApp {
    @Rule
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS);

    ......
    ......

 }

Правило @TeoraryFolder используется для создания временных папок, файлов. Каждый раз, когда выполняется метод теста, создается временная папка, которая удаляется после выполнения метода.

public class TempFolderTest {

 @Rule
 public TemporaryFolder tempFolder= new TemporaryFolder();

 @Test
 public void testTempFolder() throws IOException {
  File folder = tempFolder.newFolder("demos");
  File file = tempFolder.newFile("Hello.txt");

  assertEquals(folder.getName(), "demos");
  assertEquals(file.getName(), "Hello.txt");

 }


}

Вы можете увидеть примеры некоторых встроенных правил, предоставленных junit по этой ссылке .

Хари Кришна
источник