Как заменить аннотацию @Rule в Junit 5?

Я использую Wiremock в своих тестах и ​​имею такую ​​строку кода:

@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);

Я хочу переключиться на Junit 5. Поэтому я добавил следующую зависимость (используя gradle):

testCompile('org.junit.jupiter:junit-jupiter-engine:5.1.1')

Но нет никаких предложений, когда я пытаюсь импортировать аннотацию @Rule. Нужно ли добавить еще один модуль зависимости junit? Или правила не поддерживаются в Junit5? Если нет, то как я могу заменить аннотацию @Rule, чтобы тесты снова работали? Благодарю.

5 ответов

Решение

В общем, что вы сделали с @Rule а также @ClassRule в JUnit 4 должно быть сделано с @ExtendWith а также Extension это связано с очень близкой функцией в JUnit 5.
Он работает как стандартный JUnit, но извлекается в виде Extension учебный класс. И аналогично @Rule, так много Extension s по мере необходимости могут быть добавлены для тестового класса.

Для решения этой проблемы у вас есть несколько возможных подходов среди:

  • придерживайтесь JUnit 4 (JUnit 5 владеет частью JUnit Vintage, которая позволяет выполнять тесты JUnit 3 или 4).
  • переписать @Rule как Extension,
  • сделать фактическую обработку, выполненную WireMockRule (запустить сервер, выполнить ваши тесты и остановить сервер) в каждом тесте класса с @BeforeEach а также @AfterEach методы крючка.
  • используйте третью библиотеку, которая реализует эквивалент WireMockRule в расширении JUnit 5, например https://github.com/lanwen/wiremock-junit5

Обратите внимание, что ваша проблема уже обсуждалась в JUnit 5 Issues.

JUnit 4 аннотации @Rule а также @ClassRule в JUnit 5 не существует. По сути, существует новая модель расширений, которую можно использовать для реализации расширений с той же функциональностью. Эти расширения могут быть использованы с @ExtendWith аннотаций.

Существует ограниченная поддержка миграции для подмножества правил JUnit 4 в модуле junit-jupiter-igration support. К сожалению, он ограничен только подклассами ExternalResource а также Verifier,

Прежде чем Wiremock получит официальную поддержку JUnit, у вас есть несколько обходных путей:

  1. Проводите тесты JUnit 4 параллельно с тестами JUnit 5 с помощью junit-vintage-engine.
  2. Запустите и остановите сервер самостоятельно в тестовом коде.
  3. Используйте стороннее расширение, например wiremock-junit5 или wiremock-extension.

Теперь есть официальная поддержка JUnit 5 Jupiter из WireMock 2.31.0.

Документы здесь: http://wiremock.org/docs/junit-jupiter/

Из руководства пользователя JUnit 5 :

Однако WireMock 2.31.0 будет поставляться с полной поддержкой JUnit Jupiter, предоставляя WireMockExtension(см. комментарий к проблеме GitHub ). Текущий API:

      @ExtendWith(WireMockExtension.class)
class DeclarativeWireMockTest {

    @Test
    void test_something_with_wiremock(WireMockRuntimeInfo wmRuntimeInfo) {
        // The static DSL will be configured for you
        stubFor(get("/static-dsl").willReturn(ok()));
      
        // Instance DSL can be obtained from the runtime info parameter
        WireMock wireMock = wmRuntimeInfo.getWireMock();
        wireMock.register(get("/instance-dsl").willReturn(ok()));
        
        int port = wmRuntimeInfo.getHttpPort();
        
        // Do some testing...
    }

}

Для получения дополнительной информации ознакомьтесь с документацией в соответствующей ветке . (Я обновлю этот ответ, когда станет доступен стабильный выпуск / финальный API.)

Проект https://github.com/webcompere/java-test-gadgets позволяет решить эту проблему несколькими способами.

Вы можете использовать его поддержку правил JUnit 4 через DangerousRuleAdapter - который попытается превратить любое правило JUnit 4 в Plugin:

      @ExtendWith(PluginExtension.class)
public class DangerousRuleAdapterExampleTest {
    @Plugin
    private DangerousRuleAdapter<WireMockRule> adapter = 
        new DangerousRuleAdapter<>(new WireMockRule());

    @Test
    void theTest() {
        // use wiremock rule here
        WireMockRule rule = adapter.get();
    }

Адаптеры правил не могут работать с правилами, которые проверяют тестовый класс или тестовый метод, но делают хорошую попытку запустить правило.

Также есть поддержка запуска правила для некоторого кода:

          TemporaryFolder temporaryFolder = new TemporaryFolder();

    // let's use this temp folder with some test code
    executeWithRule(temporaryFolder, () -> {
        // here, the rule is _active_
        callSomethingThatUses(temporaryFolder.getRoot());
    });

И вы можете легко создать свой собственный новый плагин JUnit 5, используя PluginExtension а также TestResource.of

      @ExtendWith(PluginExtension.class)
class TestResourceIsActiveDuringTest {
    private WireMockServer server;

    @Plugin
    private TestResource someResource = TestResource.from(() -> server.start(),
                                                          () -> server.stop());

Другие вопросы по тегам