|
|
|
@ -866,19 +866,20 @@ however, these lifecycle annotations have limited usage within an actual test cl |
|
|
|
|
|
|
|
|
|
|
|
If a method within a test class is annotated with `@PostConstruct`, that method will be |
|
|
|
If a method within a test class is annotated with `@PostConstruct`, that method will be |
|
|
|
executed before any __before__ methods of the underlying test framework (e.g., methods |
|
|
|
executed before any __before__ methods of the underlying test framework (e.g., methods |
|
|
|
annotated with JUnit 4's `@Before`), and that will apply for every test method in the test |
|
|
|
annotated with JUnit Jupiter's `@BeforeEach`), and that will apply for every test method |
|
|
|
class. On the other hand, if a method within a test class is annotated with |
|
|
|
in the test class. On the other hand, if a method within a test class is annotated with |
|
|
|
`@PreDestroy`, that method will __never__ be executed. Within a test class it is |
|
|
|
`@PreDestroy`, that method will __never__ be executed. Within a test class it is |
|
|
|
therefore recommended to use test lifecycle callbacks from the underlying test framework |
|
|
|
therefore recommended to use test lifecycle callbacks from the underlying test framework |
|
|
|
instead of `@PostConstruct` and `@PreDestroy`. |
|
|
|
instead of `@PostConstruct` and `@PreDestroy`. |
|
|
|
==== |
|
|
|
==== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[integration-testing-annotations-junit]] |
|
|
|
[[integration-testing-annotations-junit4]] |
|
|
|
==== Spring JUnit 4 Testing Annotations |
|
|
|
==== Spring JUnit 4 Testing Annotations |
|
|
|
|
|
|
|
|
|
|
|
The following annotations are __only__ supported when used in conjunction with the |
|
|
|
The following annotations are __only__ supported when used in conjunction with the |
|
|
|
<<testcontext-junit4-runner,SpringRunner>>, <<testcontext-junit4-rules,Spring's JUnit |
|
|
|
<<testcontext-junit4-runner,SpringRunner>>, <<testcontext-junit4-rules,Spring's JUnit |
|
|
|
rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>. |
|
|
|
4 rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>. |
|
|
|
|
|
|
|
|
|
|
|
===== @IfProfileValue |
|
|
|
===== @IfProfileValue |
|
|
|
`@IfProfileValue` indicates that the annotated test is enabled for a specific testing |
|
|
|
`@IfProfileValue` indicates that the annotated test is enabled for a specific testing |
|
|
|
@ -974,6 +975,147 @@ well as any __set up__ or __tear down__ of the test fixture. |
|
|
|
} |
|
|
|
} |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[integration-testing-annotations-junit-jupiter]] |
|
|
|
|
|
|
|
==== Spring JUnit Jupiter Testing Annotations |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The following annotations are __only__ supported when used in conjunction with the |
|
|
|
|
|
|
|
`SpringExtension` and JUnit Jupiter (i.e., the programming model in JUnit 5). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
===== @SpringJUnitConfig |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`@SpringJUnitConfig` is a _composed annotation_ that combines |
|
|
|
|
|
|
|
`@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` from |
|
|
|
|
|
|
|
the Spring TestContext Framework. It can be used at the class level as a drop-in |
|
|
|
|
|
|
|
replacement for `@ContextConfiguration`. With regard to configuration options, the only |
|
|
|
|
|
|
|
difference between `@ContextConfiguration` and `@SpringJUnitConfig` is that annotated |
|
|
|
|
|
|
|
classes may be declared via the `value` attribute in `@SpringJUnitConfig`. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
**@SpringJUnitConfig**(TestConfig.class) |
|
|
|
|
|
|
|
class ConfigurationClassJUnitJupiterSpringTests { |
|
|
|
|
|
|
|
// class body... |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
**@SpringJUnitConfig**(**locations** = "/test-config.xml") |
|
|
|
|
|
|
|
class XmlJUnitJupiterSpringTests { |
|
|
|
|
|
|
|
// class body... |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See <<testcontext-ctx-management>> as well as the javadocs for `@SpringJUnitConfig` and |
|
|
|
|
|
|
|
`@ContextConfiguration` for further details. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
===== @SpringJUnitWebConfig |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`@SpringJUnitWebConfig` is a _composed annotation_ that combines |
|
|
|
|
|
|
|
`@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` and |
|
|
|
|
|
|
|
`@WebAppConfiguration` from the Spring TestContext Framework. It can be used at the class |
|
|
|
|
|
|
|
level as a drop-in replacement for `@ContextConfiguration` and `@WebAppConfiguration`. |
|
|
|
|
|
|
|
With regard to configuration options, the only difference between `@ContextConfiguration` |
|
|
|
|
|
|
|
and `@SpringJUnitWebConfig` is that annotated classes may be declared via the `value` |
|
|
|
|
|
|
|
attribute in `@SpringJUnitWebConfig`. In addition, the `value` attribute from |
|
|
|
|
|
|
|
`@WebAppConfiguration` can only be overridden via the `resourcePath` attribute in |
|
|
|
|
|
|
|
`@SpringJUnitWebConfig`. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
**@SpringJUnitWebConfig**(TestConfig.class) |
|
|
|
|
|
|
|
class ConfigurationClassJUnitJupiterSpringWebTests { |
|
|
|
|
|
|
|
// class body... |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
**@SpringJUnitWebConfig**(**locations** = "/test-config.xml") |
|
|
|
|
|
|
|
class XmlJUnitJupiterSpringWebTests { |
|
|
|
|
|
|
|
// class body... |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See <<testcontext-ctx-management>> as well as the javadocs for `@SpringJUnitWebConfig`, |
|
|
|
|
|
|
|
`@ContextConfiguration`, and `@WebAppConfiguration` for further details. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
===== @EnabledIf |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`@EnabledIf` is used to signal that the annotated JUnit Jupiter test class or test method |
|
|
|
|
|
|
|
is _enabled_ and should be executed if the supplied `expression` evaluates to `true`. |
|
|
|
|
|
|
|
Specifically, if the expression evaluates to `Boolean.TRUE` or a `String` equal to |
|
|
|
|
|
|
|
`"true"` (ignoring case), the test will be __enabled__. When applied at the class level, |
|
|
|
|
|
|
|
all test methods within that class are automatically enabled by default as well. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Expressions can be any of the following. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* Spring Expression Language (SpEL) expression – for example: |
|
|
|
|
|
|
|
- `@EnabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")` |
|
|
|
|
|
|
|
* Placeholder for a property available in the Spring `Environment` – for example: |
|
|
|
|
|
|
|
- `@EnabledIf("${smoke.tests.enabled}")` |
|
|
|
|
|
|
|
* Text literal – for example: |
|
|
|
|
|
|
|
- `@EnabledIf("true")` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note, however, that a text literal which is _not_ the result of dynamic resolution of a |
|
|
|
|
|
|
|
property placeholder is of zero practical value since `@EnabledIf("false")` is equivalent |
|
|
|
|
|
|
|
to `@Disabled` and `@EnabledIf("true")` is logically meaningless. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`@EnabledIf` may be used as a meta-annotation to create custom composed annotations. For |
|
|
|
|
|
|
|
example, a custom `@EnabledOnMac` annotation can be created as follows. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@Target({ ElementType.TYPE, ElementType.METHOD }) |
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@EnabledIf( |
|
|
|
|
|
|
|
expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}", |
|
|
|
|
|
|
|
reason = "Enabled on Mac OS" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
public @interface EnabledOnMac {} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
===== @DisabledIf |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`@DisabledIf` is used to signal that the annotated JUnit Jupiter test class or test |
|
|
|
|
|
|
|
method is _disabled_ and should not be executed if the supplied `expression` evaluates to |
|
|
|
|
|
|
|
`true`. Specifically, if the expression evaluates to `Boolean.TRUE` or a `String` equal |
|
|
|
|
|
|
|
to `"true"` (ignoring case), the test will be __disabled__. When applied at the class |
|
|
|
|
|
|
|
level, all test methods within that class are automatically disabled as well. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Expressions can be any of the following. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* Spring Expression Language (SpEL) expression – for example: |
|
|
|
|
|
|
|
- `@DisabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")` |
|
|
|
|
|
|
|
* Placeholder for a property available in the Spring `Environment` – for example: |
|
|
|
|
|
|
|
- `@DisabledIf("${smoke.tests.disabled}")` |
|
|
|
|
|
|
|
* Text literal – for example: |
|
|
|
|
|
|
|
- `@DisabledIf("true")` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note, however, that a text literal which is _not_ the result of dynamic resolution of a |
|
|
|
|
|
|
|
property placeholder is of zero practical value since `@DisabledIf("true")` is |
|
|
|
|
|
|
|
equivalent to `@Disabled` and `@DisabledIf("false")` is logically meaningless. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`@DisabledIf` may be used as a meta-annotation to create custom composed annotations. For |
|
|
|
|
|
|
|
example, a custom `@DisabledOnMac` annotation can be created as follows. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@Target({ ElementType.TYPE, ElementType.METHOD }) |
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@DisabledIf( |
|
|
|
|
|
|
|
expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}", |
|
|
|
|
|
|
|
reason = "Disabled on Mac OS" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
public @interface DisabledOnMac {} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[integration-testing-annotations-meta]] |
|
|
|
[[integration-testing-annotations-meta]] |
|
|
|
==== Meta-Annotation Support for Testing |
|
|
|
==== Meta-Annotation Support for Testing |
|
|
|
@ -1000,13 +1142,17 @@ Each of the following may be used as meta-annotations in conjunction with the |
|
|
|
* `@Sql` |
|
|
|
* `@Sql` |
|
|
|
* `@SqlConfig` |
|
|
|
* `@SqlConfig` |
|
|
|
* `@SqlGroup` |
|
|
|
* `@SqlGroup` |
|
|
|
* `@Repeat` |
|
|
|
* `@Repeat` _(JUnit 4)_ |
|
|
|
* `@Timed` |
|
|
|
* `@Timed` _(JUnit 4)_ |
|
|
|
* `@IfProfileValue` |
|
|
|
* `@IfProfileValue` _(JUnit 4)_ |
|
|
|
* `@ProfileValueSourceConfiguration` |
|
|
|
* `@ProfileValueSourceConfiguration` _(JUnit 4)_ |
|
|
|
|
|
|
|
* `@SpringJUnitConfig` _(JUnit Jupiter)_ |
|
|
|
For example, if we discover that we are repeating the following configuration |
|
|
|
* `@SpringJUnitWebConfig` _(JUnit Jupiter)_ |
|
|
|
across our JUnit 4 based test suite... |
|
|
|
* `@EnabledIf` _(JUnit Jupiter)_ |
|
|
|
|
|
|
|
* `@DisabledIf` _(JUnit Jupiter)_ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For example, if we discover that we are repeating the following configuration across our |
|
|
|
|
|
|
|
_JUnit 4_ based test suite... |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
@ -1024,8 +1170,8 @@ across our JUnit 4 based test suite... |
|
|
|
public class UserRepositoryTests { } |
|
|
|
public class UserRepositoryTests { } |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
We can reduce the above duplication by introducing a custom _composed annotation_ |
|
|
|
We can reduce the above duplication by introducing a custom _composed annotation_ that |
|
|
|
that centralizes the common test configuration like this: |
|
|
|
centralizes the common test configuration for Spring like this: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
@ -1035,25 +1181,106 @@ that centralizes the common test configuration like this: |
|
|
|
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"}) |
|
|
|
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"}) |
|
|
|
@ActiveProfiles("dev") |
|
|
|
@ActiveProfiles("dev") |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
public @interface TransactionalDevTest { } |
|
|
|
public @interface TransactionalDevTestConfig { } |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
Then we can use our custom `@TransactionalDevTest` annotation to simplify the |
|
|
|
Then we can use our custom `@TransactionalDevTestConfig` annotation to simplify the |
|
|
|
configuration of individual test classes as follows: |
|
|
|
configuration of individual JUnit 4 based test classes as follows: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
---- |
|
|
|
---- |
|
|
|
@RunWith(SpringRunner.class) |
|
|
|
@RunWith(SpringRunner.class) |
|
|
|
@TransactionalDevTest |
|
|
|
@TransactionalDevTestConfig |
|
|
|
public class OrderRepositoryTests { } |
|
|
|
public class OrderRepositoryTests { } |
|
|
|
|
|
|
|
|
|
|
|
@RunWith(SpringRunner.class) |
|
|
|
@RunWith(SpringRunner.class) |
|
|
|
@TransactionalDevTest |
|
|
|
@TransactionalDevTestConfig |
|
|
|
public class UserRepositoryTests { } |
|
|
|
public class UserRepositoryTests { } |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
For further details, consult the <<core.adoc#annotation-programming-model,Spring Annotation Programming Model>>. |
|
|
|
If we are writing tests using JUnit Jupiter, we can reduce code duplication even further |
|
|
|
|
|
|
|
since annotations in JUnit 5 can also be used as meta-annotations. For example, if we |
|
|
|
|
|
|
|
discover that we are repeating the following configuration across our JUnit Jupiter based |
|
|
|
|
|
|
|
test suite... |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@ExtendWith(SpringExtension.class) |
|
|
|
|
|
|
|
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"}) |
|
|
|
|
|
|
|
@ActiveProfiles("dev") |
|
|
|
|
|
|
|
@Transactional |
|
|
|
|
|
|
|
class OrderRepositoryTests { } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ExtendWith(SpringExtension.class) |
|
|
|
|
|
|
|
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"}) |
|
|
|
|
|
|
|
@ActiveProfiles("dev") |
|
|
|
|
|
|
|
@Transactional |
|
|
|
|
|
|
|
class UserRepositoryTests { } |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
We can reduce the above duplication by introducing a custom _composed annotation_ |
|
|
|
|
|
|
|
that centralizes the common test configuration for Spring and JUnit Jupiter like this: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@Target(ElementType.TYPE) |
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@ExtendWith(SpringExtension.class) |
|
|
|
|
|
|
|
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"}) |
|
|
|
|
|
|
|
@ActiveProfiles("dev") |
|
|
|
|
|
|
|
@Transactional |
|
|
|
|
|
|
|
public @interface TransactionalDevTestConfig { } |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Then we can use our custom `@TransactionalDevTestConfig` annotation to simplify the |
|
|
|
|
|
|
|
configuration of individual JUnit Jupiter based test classes as follows: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@TransactionalDevTestConfig |
|
|
|
|
|
|
|
class OrderRepositoryTests { } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@TransactionalDevTestConfig |
|
|
|
|
|
|
|
class UserRepositoryTests { } |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Since JUnit Jupiter supports the use of `@Test`, `@RepeatedTest`, `ParameterizedTest`, |
|
|
|
|
|
|
|
etc. as meta-annotations, it is also possible to create custom composed annotations at |
|
|
|
|
|
|
|
the test method level. For example, if we wish to create a _composed annotation_ that |
|
|
|
|
|
|
|
combines the `@Test` and `@Tag` annotations from JUnit Jupiter with the `@Transactional` |
|
|
|
|
|
|
|
annotation from Spring, we could create an `@TransactionalIntegrationTest` annotation as |
|
|
|
|
|
|
|
follows. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@Target(ElementType.METHOD) |
|
|
|
|
|
|
|
@Retention(RetentionPolicy.RUNTIME) |
|
|
|
|
|
|
|
@Transactional |
|
|
|
|
|
|
|
@Tag("integration-test") // org.junit.jupiter.api.Tag |
|
|
|
|
|
|
|
@Test // org.junit.jupiter.api.Test |
|
|
|
|
|
|
|
public @interface TransactionalIntegrationTest { } |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Then we can use our custom `@TransactionalIntegrationTest` annotation to simplify the |
|
|
|
|
|
|
|
configuration of individual JUnit Jupiter based test methods as follows: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
@TransactionalIntegrationTest |
|
|
|
|
|
|
|
void saveOrder() { } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@TransactionalIntegrationTest |
|
|
|
|
|
|
|
void deleteOrder() { } |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For further details, consult the <<core.adoc#annotation-programming-model,Spring |
|
|
|
|
|
|
|
Annotation Programming Model>>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[testcontext-framework]] |
|
|
|
[[testcontext-framework]] |
|
|
|
@ -1066,15 +1293,17 @@ configuration__ with reasonable defaults that can be overridden through annotati |
|
|
|
configuration. |
|
|
|
configuration. |
|
|
|
|
|
|
|
|
|
|
|
In addition to generic testing infrastructure, the TestContext framework provides |
|
|
|
In addition to generic testing infrastructure, the TestContext framework provides |
|
|
|
explicit support for JUnit 4 and TestNG in the form of `abstract` support classes. For |
|
|
|
explicit support for JUnit 4, JUnit Jupiter (a.k.a., JUnit 5), and TestNG. For JUnit 4 |
|
|
|
JUnit 4, Spring also provides a custom JUnit `Runner` and custom JUnit `Rules` that allow |
|
|
|
and TestNG, Spring provides `abstract` support classes. Furthermore, Spring provides a |
|
|
|
one to write so-called __POJO test classes__. POJO test classes are not required to |
|
|
|
custom JUnit `Runner` and custom JUnit `Rules` for _JUnit 4_ as well as a custom |
|
|
|
extend a particular class hierarchy. |
|
|
|
`Extension` for _JUnit Jupiter_ that allow one to write so-called __POJO test classes__. |
|
|
|
|
|
|
|
POJO test classes are not required to extend a particular class hierarchy such as the |
|
|
|
The following section provides an overview of the internals of the TestContext |
|
|
|
`abstract` support classes. |
|
|
|
framework. If you are only interested in _using_ the framework and not necessarily |
|
|
|
|
|
|
|
interested in _extending_ it with your own custom listeners or custom loaders, feel free |
|
|
|
The following section provides an overview of the internals of the TestContext framework. |
|
|
|
to go directly to the configuration (<<testcontext-ctx-management,context management>>, |
|
|
|
If you are only interested in _using_ the framework and not necessarily interested in |
|
|
|
|
|
|
|
_extending_ it with your own custom listeners or custom loaders, feel free to go directly |
|
|
|
|
|
|
|
to the configuration (<<testcontext-ctx-management,context management>>, |
|
|
|
<<testcontext-fixture-di,dependency injection>>, <<testcontext-tx,transaction |
|
|
|
<<testcontext-fixture-di,dependency injection>>, <<testcontext-tx,transaction |
|
|
|
management>>), <<testcontext-support-classes,support classes>>, and |
|
|
|
management>>), <<testcontext-support-classes,support classes>>, and |
|
|
|
<<integration-testing-annotations,annotation support>> sections. |
|
|
|
<<integration-testing-annotations,annotation support>> sections. |
|
|
|
@ -1085,14 +1314,14 @@ management>>), <<testcontext-support-classes,support classes>>, and |
|
|
|
The core of the framework consists of the `TestContextManager` class and the |
|
|
|
The core of the framework consists of the `TestContextManager` class and the |
|
|
|
`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A |
|
|
|
`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A |
|
|
|
`TestContextManager` is created per test class (e.g., for the execution of all test |
|
|
|
`TestContextManager` is created per test class (e.g., for the execution of all test |
|
|
|
methods within a single test class in JUnit 4). The `TestContextManager` in turn manages a |
|
|
|
methods within a single test class in JUnit Jupiter). The `TestContextManager` in turn |
|
|
|
`TestContext` that holds the context of the current test. The `TestContextManager` also |
|
|
|
manages a `TestContext` that holds the context of the current test. The |
|
|
|
updates the state of the `TestContext` as the test progresses and delegates to |
|
|
|
`TestContextManager` also updates the state of the `TestContext` as the test progresses |
|
|
|
`TestExecutionListener` implementations, which instrument the actual test execution by |
|
|
|
and delegates to `TestExecutionListener` implementations, which instrument the actual |
|
|
|
providing dependency injection, managing transactions, and so on. A `SmartContextLoader` |
|
|
|
test execution by providing dependency injection, managing transactions, and so on. A |
|
|
|
is responsible for loading an `ApplicationContext` for a given test class. Consult the |
|
|
|
`SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test |
|
|
|
javadocs and the Spring test suite for further information and examples of various |
|
|
|
class. Consult the javadocs and the Spring test suite for further information and |
|
|
|
implementations. |
|
|
|
examples of various implementations. |
|
|
|
|
|
|
|
|
|
|
|
===== TestContext |
|
|
|
===== TestContext |
|
|
|
`TestContext` encapsulates the context in which a test is executed, agnostic of the |
|
|
|
`TestContext` encapsulates the context in which a test is executed, agnostic of the |
|
|
|
@ -3090,11 +3319,11 @@ transaction method__ or __after transaction method__ is executed at the appropri |
|
|
|
|
|
|
|
|
|
|
|
[TIP] |
|
|
|
[TIP] |
|
|
|
==== |
|
|
|
==== |
|
|
|
Any __before methods__ (such as methods annotated with JUnit 4's `@Before`) and any __after |
|
|
|
Any __before methods__ (such as methods annotated with JUnit Jupiter's `@BeforeEach`) and |
|
|
|
methods__ (such as methods annotated with JUnit 4's `@After`) are executed __within__ a |
|
|
|
any __after methods__ (such as methods annotated with JUnit Jupiter's `@AfterEach`) are |
|
|
|
transaction. In addition, methods annotated with `@BeforeTransaction` or |
|
|
|
executed __within__ a transaction. In addition, methods annotated with |
|
|
|
`@AfterTransaction` are naturally not executed for test methods that are not configured |
|
|
|
`@BeforeTransaction` or `@AfterTransaction` are naturally not executed for test methods |
|
|
|
to run within a transaction. |
|
|
|
that are not configured to run within a transaction. |
|
|
|
==== |
|
|
|
==== |
|
|
|
|
|
|
|
|
|
|
|
[[testcontext-tx-mgr-config]] |
|
|
|
[[testcontext-tx-mgr-config]] |
|
|
|
@ -3112,7 +3341,7 @@ used to look up a transaction manager in the test's `ApplicationContext`. |
|
|
|
[[testcontext-tx-annotation-demo]] |
|
|
|
[[testcontext-tx-annotation-demo]] |
|
|
|
===== Demonstration of all transaction-related annotations |
|
|
|
===== Demonstration of all transaction-related annotations |
|
|
|
|
|
|
|
|
|
|
|
The following JUnit 4 based example displays a fictitious integration testing scenario |
|
|
|
The following JUnit 4 based example displays a _fictitious_ integration testing scenario |
|
|
|
highlighting all transaction-related annotations. The example is **not** intended to |
|
|
|
highlighting all transaction-related annotations. The example is **not** intended to |
|
|
|
demonstrate best practices but rather to demonstrate how these annotations can be used. |
|
|
|
demonstrate best practices but rather to demonstrate how these annotations can be used. |
|
|
|
Consult the <<integration-testing-annotations,annotation support>> section for further |
|
|
|
Consult the <<integration-testing-annotations,annotation support>> section for further |
|
|
|
|