The Service class is the foundation of TNB’s testing framework. Every System-X service extends this abstract class, which provides a consistent interface for accessing accounts, clients, and validation helpers.
The Service class is a generic abstract class that manages three key components:
public abstract class Service<A extends Account, C, V extends Validation> implements BeforeAllCallback, AfterAllCallback { protected A account; protected C client; protected V validation; public A account() { if (account == null) { Class<A> accountClass = (Class<A>) ReflectionUtil.getGenericTypesOf(Service.class, this.getClass())[0]; account = AccountFactory.create(accountClass); } return account; } protected C client() { return client; } public V validation() { return validation; }}
The Service class implements JUnit 5’s BeforeAllCallback and AfterAllCallback interfaces, enabling automatic lifecycle management when used with @RegisterExtension.
The ServiceFactory class provides factory methods for creating service instances:
public class KafkaTest { @RegisterExtension public static Kafka kafka = ServiceFactory.create(Kafka.class); @Test public void testWithKafka() { final String topic = "myTopic"; final String message = "Hello kafka!"; kafka.validation().produce(topic, message); final List<ConsumerRecord<String, String>> records = kafka.validation().consume(topic); Assertions.assertEquals(1, records.size()); Assertions.assertEquals(message, records.get(0).value()); }}
Uses Java’s ServiceLoader to discover implementations
If multiple implementations exist (e.g., LocalKafka and OpenshiftKafka), selects based on:
The test.use.openshift system property
Implementation priority
Enabled status
Returns the appropriate instance
Relevant code from ServiceFactory.java:40-64:
if (loader.stream().count() == 1) { return loader.findFirst().get();}// Sort the services based on the priority and then return the first one that is enabledOptional<S> service = StreamSupport.stream(loader.spliterator(), false) .sorted((s1, s2) -> ((Deployable) s2).priority() - ((Deployable) s1).priority()) .filter(s -> ((Deployable) s).enabled()) .findFirst();