Как заменить аннотацию @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, у вас есть несколько обходных путей:
- Проводите тесты JUnit 4 параллельно с тестами JUnit 5 с помощью junit-vintage-engine.
- Запустите и остановите сервер самостоятельно в тестовом коде.
- Используйте стороннее расширение, например wiremock-junit5 или wiremock-extension.
Теперь есть официальная поддержка JUnit 5 Jupiter из WireMock 2.31.0.
Документы здесь: http://wiremock.org/docs/junit-jupiter/
Из руководства пользователя JUnit 5 :
@Rule
а также@ClassRule
Больше не существует; заменен@ExtendWith
а также@RegisterExtension
- См. Также Ограниченная поддержка правил JUnit 4 .
Однако 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());