Главная страница

Basic Java Tools for Building & Testing Apps


Скачать 4.76 Mb.
НазваниеBasic Java Tools for Building & Testing Apps
АнкорJUNIt
Дата14.11.2022
Размер4.76 Mb.
Формат файлаpdf
Имя файла5_2_0_Maven_JUnit_Tutorial.pdf
ТипРеферат
#787190
страница13 из 16
1   ...   8   9   10   11   12   13   14   15   16
4.5. Обработка исключений
И последнее, но не менее важное: интерфейс TestExecutionExceptionHandler можно использовать для определения поведения теста при обнаружении определенных типов исключений.
Например, мы можем создать расширение, которое будет регистрировать и игнорировать все исключения типа FileNotFoundException , при этом перебрасывая любой другой тип: public class
IgnoreFileNotFoundExceptionExtension implements
TestExecutionExceptionHandler
{
Logger logger = LogManager
.getLogger(IgnoreFileNotFoundExceptionExtension.class);
@Override public void handleTestExecutionException
(ExtensionContext context,
Throwable throwable) throws
Throwable { if
(throwable instanceof
FileNotFoundException) { logger.error(
"File not found:"
+ throwable.getMessage()); return
;
} throw throwable;

}
}
5. Регистрация расширений
Теперь, когда мы определили наши тестовые расширения, нам нужно зарегистрировать их с помощью теста JUnit 5.
Чтобы достичь этого, мы можем использовать аннотацию @ ExtendWith .
Аннотацию можно добавить несколько раз в тест или получить список расширений в качестве параметра:
@ExtendWith
({ EnvironmentExtension.class,
EmployeeDatabaseSetupExtension.class, EmployeeDaoParameterResolver.class })
@ExtendWith
(LoggingExtension.class)
@ExtendWith
(IgnoreFileNotFoundExceptionExtension.class) public class
EmployeesTest
{ private
EmployeeJdbcDao employeeDao; private
Logger logger; public
EmployeesTest
(EmployeeJdbcDao employeeDao) { this
.employeeDao = employeeDao;
}
@Test public void whenAddEmployee__thenGetEmployee
() throws
SQLException {
Employee emp = new
Employee(
1
,
"john"
); employeeDao.add(emp); assertEquals(
1
, employeeDao.findAll().size());
}
@Test public void whenGetEmployees__thenEmptyList
() throws
SQLException { assertEquals(
0
, employeeDao.findAll().size());
} public void setLogger
(Logger logger) { this
.logger = logger;
}
}
Мы видим, что в нашем тестовом классе есть конструктор с параметром EmployeeJdbcDao , который будет разрешен путем расширения расширения EmployeeDaoParameterResolver .
При добавлении EnvironmentExtension наш тест будет выполняться только в среде, отличной от "qa"
В нашем тесте также будет создана таблица employees и каждый метод будет заключен в транзакцию путем добавления EmployeeDatabaseSetupExtension .
Даже если сначала выполняется тест whenAddEmployee thenGetEmploee () __, который добавляет одну запись в таблицу, второй тест найдет 0 записей в таблице.
Экземпляр регистратора будет добавлен в наш класс с помощью LoggingExtension .
Наконец, наш тестовый класс будет игнорировать все экземпляры FileNotFoundException , так как он добавляет соответствующее расширение.
5.1. Автоматическая регистрация продления
Если мы хотим зарегистрировать расширение для всех тестов в нашем приложении, мы можем сделать это, добавив полное имя в файл /META-INF/services/org.junit.jupiter.api.extension.Extension : com.baeldung.extensions.LoggingExtension
Чтобы этот механизм был включен, нам также нужно установить для ключа конфигурации junit.extensions.autodetection.enabled значение true. Это можно сделать, запустив JVM со свойством
Djunit.extensions.autodetection.enabled = true или добавив параметр конфигурации в LauncherDiscoveryRequest :
LauncherDiscoveryRequest request

= LauncherDiscoveryRequestBuilder.request()
.selectors(selectClass(
"com.baeldung.EmployeesTest"
))
.configurationParameter(
"junit.extensions.autodetection.enabled"
,
"true"
)
.build();
6. Заключение
В этом руководстве мы показали, как мы можем использовать модель расширений JUnit 5 для создания пользовательских тестовых расширений
Mockito и JUnit 5 - Использование


Testing
Mockito
JUnit 5
FacebookTumblrPinterestPocketEvernoteTwitterLineEmailRedditDiggVKРесурс
1. Вступление
В этой быстрой статье мы покажем , как интегрировать Mockito с моделью расширения JUnit 5 . Чтобы узнать больше о модели расширения JUnit 5, взгляните на этот article
Сначала мы покажем, как создать расширение, которое автоматически создает фиктивные объекты для любого атрибута класса или параметра метода, помеченного @ Mock .
Затем мы будем использовать наше расширение Mockito в тестовом классе JUnit 5.
2. Зависимости Maven
2.1. Обязательные зависимости
Давайте добавим зависимости JUnit 5 (jupiter) и mockito в наш pom.xml :
<
dependency
>
<
groupId
>org.junit.jupitergroupId
>
<
artifactId
>junit-jupiter-engineartifactId
>
<
version
>5.3.1version
>
<
scope
>testscope
>
dependency
>
<
dependency
>
<
groupId
>org.mockitogroupId
>
<
artifactId
>mockito-coreartifactId
>
<
version
>2.21.0version
>
<
scope
>testscope
>
dependency
>
Обратите внимание, что _unit-jupiter-engine - это основная библиотека JUnit 5, а junit-platform-launcher_ используется с плагином Maven и средством запуска IDE.
2.2. Плагин Surefire
Давайте также сконфигурируем плагин Maven Surefire для запуска наших тестовых классов с помощью новой платформы запуска JUnit:
<
plugin
>
<
artifactId
>maven-surefire-pluginartifactId
>
<
version
>2.19.1version
>
<
dependencies
>
<
dependency
>
<
groupId
>org.junit.platformgroupId
>
<
artifactId
>junit-platform-surefire-providerartifactId
>
<
version
>1.0.1version
>
dependency
>
dependencies
>
plugin
>
2.3. Зависимости JUnit 4 IDE
Чтобы наши тесты были совместимы с JUnit4 (vintage), для IDE, которые еще не поддерживают JUnit 5, давайте включим следующие зависимости:
<
dependency
>
<
groupId
>org.junit.platformgroupId
>
<
artifactId
>junit-platform-runnerartifactId
>
<
version
>1.2.0version
>
<
scope
>testscope
>
dependency
>
<
dependency
>
<
groupId
>org.junit.vintagegroupId
>

<
artifactId
>junit-vintage-engineartifactId
>
<
version
>5.2.0version
>
<
scope
>testscope
>
dependency
>
Кроме того, мы должны рассмотреть возможность аннотирования всех наших тестовых классов с помощью @ RunWith
(JUnitPlatform.class)
Последние версии
junit-jupiter-engine
, https://search.maven.org/classic/#search
% 7Cga% 7C1% 7Cjunit% 20vintage%
20engine[junit-vintage-engine],
junit-platform-launcher
, и
mockito-core
можно загрузить из Maven Central.
3. Расширение Mockito
Mockito обеспечивает реализацию расширений JUnit5 в библиотеке -
https://search.maven.org/search?
Q = a: mockito-
junit-jupiter[mockito-junit-jupiter]
Мы включим эту зависимость в наш pom.xml:
<
dependency
>
<
groupId
>org.mockitogroupId
>
<
artifactId
>mockito-junit-jupiterartifactId
>
<
version
>2.23.0version
>
<
scope
>testscope
>
dependency
>
4. Создание тестового класса
Давайте создадим наш тестовый класс и добавим к нему расширение Mockito:
@ExtendWith
(MockitoExtension.class)
@RunWith
(JUnitPlatform.class) public class
UserServiceUnitTest
{
UserService userService;
//}
Мы можем использовать аннотацию @ Mock , чтобы добавить макет для переменной экземпляра, которую мы можем использовать в любом месте тестового класса:
@Mock
UserRepository userRepository;
Также мы можем ввести фиктивные объекты в параметры метода:
@BeforeEach void init
(@Mock SettingRepository settingRepository) { userService = new
DefaultUserService(userRepository, settingRepository, mailClient);
Mockito.lenient().when(settingRepository.getUserMinAge()).thenReturn(
10
); when(settingRepository.getUserNameMinLength()).thenReturn(
4
);
Mockito.lenient().when(userRepository.isUsernameAlreadyExists(any(String.class))).thenRetur n(
false
);
}
Пожалуйста, обратите внимание на использование Mockito.lenient () здесь. Mockito создает исключение UnsupportedStubbingException, когда инициализированный макет не вызывается одним из методов теста во время выполнения. Мы можем избежать этой строгой проверки заглушки, используя этот метод при инициализации макетов.
Мы можем даже вставить фиктивный объект в параметр метода тестирования:
@Test void givenValidUser__whenSaveUser__thenSucceed
(@Mock MailClient mailClient) {
//Given user = new
User(
"Jerry"
,
12
); when(userRepository.insert(any(User.class))).then(
new
Answer() { int sequence =
1
;

@Override public
User answer
(InvocationOnMock invocation) throws
Throwable {
User user = (User) invocation.getArgument(
0
); user.setId(sequence++); return user;
}
}); userService = new
DefaultUserService(userRepository, settingRepository, mailClient);
//When
User insertedUser = userService.register(user);
//Then verify(userRepository).insert(user);
Assertions.assertNotNull(user.getId()); verify(mailClient).sendUserRegistrationMail(insertedUser);
}
Обратите внимание, что макет MailClient , который мы вводим в качестве тестового параметра, НЕ будет тем же экземпляром, который мы добавили в метод init .
5. Заключение
Junit 5 предоставил хорошую модель для расширения. Мы продемонстрировали простое расширение Mockito, которое упростило нашу логику создания макетов
Conditional Test Execution
The
ExecutionCondition extension API in JUnit Jupiter allows developers to either enable or disable a container or test based on certain conditions programmatically. The simplest example of such a condition is the built-in
DisabledCondition which supports the
@Disabled annotation (see
Disabling Tests
). In addition to
@Disabled
, JUnit Jupiter also supports several other annotation-based conditions in the org.junit.jupiter.api.condition package that allow developers to enable or disable containers and tests declaratively. When multiple
ExecutionCondition extensions are registered, a container or test is disabled as soon as one of the conditions returns disabled. If you wish to provide details about why they might be disabled, every annotation associated with these built-in conditions has a disabledReason attribute available for that purpose.
See
ExecutionCondition and the following sections for details.
Composed Annotations
Note that any of the conditional annotations listed in the following sections may also be used as a meta-annotation in order to create a custom composed annotation. For example, the
@TestOnMac annotation in the
@EnabledOnOs demo shows how you can combine
@Test and
@EnabledOnOs in a single, reusable annotation.
Unless otherwise stated, each of the conditional annotations listed in the following sections can only be declared once on a given test interface, test class, or test method. If a conditional annotation is directly present, indirectly present, or meta-present multiple times on a given element, only the first such annotation discovered by JUnit will be used; any additional declarations will be silently ignored. Note, however, that each conditional annotation may be used in conjunction with other conditional annotations in the org.junit.jupiter.api.condition package.
2.7.1. Operating System Conditions
A container or test may be enabled or disabled on a particular operating system via the
@EnabledOnOs and
@DisabledOnOs annotations.

@Test
@EnabledOnOs
(
MAC
)
void
onlyOnMacOs
() {
// ...
}
@TestOnMac
void
testOnMac
() {
// ...
}
@Test
@EnabledOnOs
({
LINUX
,
MAC
})
void
onLinuxOrMac
() {
// ...
}
@Test
@DisabledOnOs
(
WINDOWS
)
void
notOnWindows
() {
// ...
}
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Test
@EnabledOnOs
(
MAC
)
@interface
TestOnMac
{
}
2.7.2. Java Runtime Environment Conditions
A container or test may be enabled or disabled on particular versions of the Java Runtime Environment (JRE) via the
@EnabledOnJre and
@DisabledOnJre annotations or on a particular range of versions of the JRE via the
@EnabledForJreRange and
@DisabledForJreRange annotations. The range defaults to
JRE
.JAVA_8
as the lower border (
min
) and
JRE
.OTHER
as the higher border (
max
), which allows usage of half open ranges.
@Test
@EnabledOnJre
(
JAVA_8
)
void
onlyOnJava8
() {
// ...
}
@Test
@EnabledOnJre
({
JAVA_9
,
JAVA_10
})
void
onJava9Or10
() {
// ...
}
@Test
@EnabledForJreRange
(min =
JAVA_9
, max =
JAVA_11
)
void
fromJava9to11
() {
// ...
}
@Test
@EnabledForJreRange
(min =
JAVA_9
)
void
fromJava9toCurrentJavaFeatureNumber
() {
// ...
}
@Test
@EnabledForJreRange
(max =
JAVA_11
)
void
fromJava8To11
() {
// ...
}
@Test

@DisabledOnJre
(
JAVA_9
)
void
notOnJava9
() {
// ...
}
@Test
@DisabledForJreRange
(min =
JAVA_9
, max =
JAVA_11
)
void
notFromJava9to11
() {
// ...
}
@Test
@DisabledForJreRange
(min =
JAVA_9
)
void
notFromJava9toCurrentJavaFeatureNumber
() {
// ...
}
@Test
@DisabledForJreRange
(max =
JAVA_11
)
void
notFromJava8to11
() {
// ...
}
2.7.3. System Property Conditions
A container or test may be enabled or disabled based on the value of the named
JVM system property via the
@EnabledIfSystemProperty and
@DisabledIfSystemProperty annotations. The value supplied via the matches attribute will be interpreted as a regular expression.
@Test
@EnabledIfSystemProperty
(named =
"os.arch"
, matches =
".*64.*"
)
void
onlyOn64BitArchitectures
() {
// ...
}
@Test
@DisabledIfSystemProperty
(named =
"ci-server"
, matches =
"true"
)
void
notOnCiServer
() {
// ...
}
As of JUnit Jupiter
5.6,
@EnabledIfSystemProperty and
@DisabledIfSystemProperty are repeatable
annotations. Consequently, these annotations may be declared multiple times on a test interface, test class, or test method. Specifically, these annotations will be found if they are directly present, indirectly present, or meta-present on a given element.
2.7.4. Environment Variable Conditions
A container or test may be enabled or disabled based on the value of the named environment variable from the underlying operating system via the
@EnabledIfEnvironmentVariable and
@DisabledIfEnvironmentVariable annotations. The value supplied via the matches attribute will be interpreted as a regular expression.
@Test
@EnabledIfEnvironmentVariable
(named =
"ENV"
, matches =
"staging-server"
)
void
onlyOnStagingServer
() {
// ...
}
@Test
@DisabledIfEnvironmentVariable
(named =
"ENV"
, matches =
".*development.*"
)
void
notOnDeveloperWorkstation
() {
// ...
}

As of JUnit Jupiter
5.6,
@EnabledIfEnvironmentVariable and
@DisabledIfEnvironmentVariable are repeatable
annotations. Consequently, these annotations may be declared multiple times on a test interface, test class, or test method. Specifically, these annotations will be found if they are directly present, indirectly present, or meta-present on a given element.
2.7.5. Custom Conditions
A container or test may be enabled or disabled based on the boolean return of a method via the
@EnabledIf and
@DisabledIf annotations.
The method is provided to the annotation via its name, or its fully qualified name if located outside the test class. If needed, the condition method can take a single parameter of type
ExtensionContext
1   ...   8   9   10   11   12   13   14   15   16


написать администратору сайта