Class Extension_MatsAnnotatedClass
- java.lang.Object
-
- io.mats3.test.abstractunit.AbstractMatsAnnotatedClass
-
- io.mats3.test.jupiter.Extension_MatsAnnotatedClass
-
- All Implemented Interfaces:
org.junit.jupiter.api.extension.AfterEachCallback,org.junit.jupiter.api.extension.BeforeEachCallback,org.junit.jupiter.api.extension.Extension
public final class Extension_MatsAnnotatedClass extends io.mats3.test.abstractunit.AbstractMatsAnnotatedClass implements org.junit.jupiter.api.extension.BeforeEachCallback, org.junit.jupiter.api.extension.AfterEachCallbackHelper class to test Mats3 Endpoints which are defined using the Mats3 SpringConfig annotations, but without using the full Spring harness for testing. That is, you write tests in a "pure Java" style, but can still test your Mats3 SpringConfig annotation defined Mats endpoints. This can be terser and faster than using the full Spring test harness.By having at least one such test per SpringConfig defined Mats3 endpoints, you ensure an integration test of the SpringConfig aspects of your Mats endpoints: The annotations are read, the endpoint is set up, and the STOs (state) and DTOs (data) can be instantiated and serialized. For corner case unit testing where you want lots of tests, you can instead invoke the individual methods directly on the instantiated endpoint class, thus getting the fastests speeds.
The solution creates a Spring context internally to initialize the Mats endpoints, but this should be viewed as an implementation detail, and the Spring context is not made available for the test - the specified SpringConfig annotated endpoints just turns up in the MatsFactory so that you can test it using e.g. the MatsFuturizer. The Spring context is created anew for each test, and is not shared between tests. Endpoints specified at the Extension's field init will be registered anew on the provided
MatsFactoryfor each test method. All Endpoints are deleted after the test method has run. (The supplied MatsFactory and its underlying MQ Broker is shared between all tests.)"Field beans" dependency injection and dependency overriding: Fields in the test class are read out, and entered as beans into the Spring context, thus made available for injection into the Mats annotated classes when using the
withAnnotatedMatsClasses(Class...)method. Overriding: When using Jupiter's @Nested feature, you may override fields from the outer test class by declaring a field with the same type in the inner @Nested test class. There is no support for qualifiers, so if your Mats-annotated endpoints require multiple beans of the same type (made unique by qualifiers), you will have to use a full Spring setup for your tests.MatsFactory qualifiers: If the Mats annotated endpoints has qualifiers for the MatsFactory, these will be ignored. For the same reason, any duplicate endpointIds will be ignored, and only one instance will be registered: The reason for using qualifiers are that you have multiple MatsFactories in the application, and some endpoints might be registered on multiple MatsFactories (repeating the annotation with the same endpointId, but with different qualifier). For the testing scenario using this class, we only have one MatsFactory, which will be used for all endpoints, and duplicates will thus have to be ignored. If this is a problem, you will have to use a full Spring setup for your tests.
Classes with SpringConfig Mats3 Endpoints can either be registered using the
withAnnotatedMatsClasses(Class...)method, or by using thewithAnnotatedMatsInstances(Object...)method. This can both be done at the field initialization of the Extension, or inside the test method.The classes-variant is intended to be used on creation of the Extension, i.e. at the field initialization point - but can also be used inside the test method. Technically, it will register the class in a Spring context, and put all the fields of the test class as beans available for injection on that class - that is, dependencies in the Mats3 annotated classes will be resolved using the fields of the test class. It is important that fields are initialized before this extension runs, if there are dependencies in the test class needed by the Mats annotated class. When using Mockito and the
@Mockannotation, this is resolved automatically, since Mockito will initialize the fields before the Extension is created. Mockito is started as normal, by annotating the test class with@ExtendWith(MockitoExtension.class).The instances-variant registers the Mats annotated class as an Endpoint when called. You will then have to initialize the class yourself, before registering it, probably using the constructor used when Spring otherwise would constructor-inject the instance. This is relevant if you only have a few tests that need the endpoint, and possibly other tests that are unit testing by calling directly on an instance of the class (i.e. calling directly on the
@MatsMappingor@Stagemethods).There are multiple examples in the test classes.
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidafterEach(org.junit.jupiter.api.extension.ExtensionContext context)voidbeforeEach(org.junit.jupiter.api.extension.ExtensionContext extensionContext)static Extension_MatsAnnotatedClasscreate()Create a new instance without MatsFactory - which will be found through the ExtensionContext ifExtension_Matsis also used.static Extension_MatsAnnotatedClasscreate(io.mats3.MatsFactory matsFactory)Create a new instance based on the suppliedMatsFactoryinstance.static Extension_MatsAnnotatedClasscreate(Extension_Mats extensionMats)Create a new instance based on aExtension_Matsinstance (from which the needed MatsFactory is gotten).Extension_MatsAnnotatedClasswithAnnotatedMatsClasses(java.lang.Class<?>... annotatedMatsClasses)Add classes to act as a source for annotations to register Mats endpoints for each test.Extension_MatsAnnotatedClasswithAnnotatedMatsInstances(java.lang.Object... annotatedMatsInstances)Add instances of classes annotated with Mats annotations to register Mats endpoints for each test.
-
-
-
Method Detail
-
create
public static Extension_MatsAnnotatedClass create()
Create a new instance without MatsFactory - which will be found through the ExtensionContext ifExtension_Matsis also used.- Returns:
- a new
Extension_MatsAnnotatedClass
-
create
public static Extension_MatsAnnotatedClass create(io.mats3.MatsFactory matsFactory)
Create a new instance based on the suppliedMatsFactoryinstance.- Parameters:
matsFactory-MatsFactoryon which to register Mats endpoints for each test.- Returns:
- a new
Extension_MatsAnnotatedClass
-
create
public static Extension_MatsAnnotatedClass create(Extension_Mats extensionMats)
Create a new instance based on aExtension_Matsinstance (from which the needed MatsFactory is gotten).- Parameters:
extensionMats-Extension_Matsto read theMatsFactoryfrom, on which to register Mats endpoints for each test.- Returns:
- a new
Extension_MatsAnnotatedClass
-
withAnnotatedMatsClasses
public Extension_MatsAnnotatedClass withAnnotatedMatsClasses(java.lang.Class<?>... annotatedMatsClasses)
Add classes to act as a source for annotations to register Mats endpoints for each test.
-
withAnnotatedMatsInstances
public Extension_MatsAnnotatedClass withAnnotatedMatsInstances(java.lang.Object... annotatedMatsInstances)
Add instances of classes annotated with Mats annotations to register Mats endpoints for each test.
-
beforeEach
public void beforeEach(org.junit.jupiter.api.extension.ExtensionContext extensionContext)
- Specified by:
beforeEachin interfaceorg.junit.jupiter.api.extension.BeforeEachCallback
-
afterEach
public void afterEach(org.junit.jupiter.api.extension.ExtensionContext context)
- Specified by:
afterEachin interfaceorg.junit.jupiter.api.extension.AfterEachCallback
-
-