The SORMAS backend layer is the implementation of the sormas-api
and gives access to the data and logic of SORMAS. It contains a big set of facades and services that are origanized based on the different entities and their domains, like case surveillance and contact tracing.
- Junit 5 is the core testing framework used here.
- Hamcrest is used to define declarative matchers.
A good tutorial can be found here: Hamcrest Guide. - Mockito is used to mock unavailable or unwanted behaviour of classes and methods.
An extensive tutorial can be found here: Mockito Tutorial.
The relevant aspects of Jakarta EE are covered in the following sub chapters.
Most important:
- The
AbstractBeanTest
class should be used as a super class for all EJB unit test classes. It initializes all needed mocks (e.g.javax.ejb.SessionContext
) and provides some utility methods likeloginWith
andexecuteInTransaction
(see below). - The TestDataCreator class should be used to generated test entities and dtos where needed.
cdi-test boots a cdi container once for all tests using Weld (cdi reference implementation).
This means you can make full use of cdi annotations like @Inject
.
cdi-test imitates this by adding cdi annotations to classes annotated with bean annotiations like @Stateless
.
This means all EJB classes can be used in test classes by injecting them.
You can mock beans as explained here: Mocking Beans
Those mocks will automatically replace all usages of the bean, so you don't have to use the @InjectMocks
annotation.
As an alternative you can inherit beans in test implementations as explained here: Test Implementations
This allows you to only override a part of the beans logic, keeping the other functionality as-is.
java.security.Principal
is mocked. You can use AbstractBeanTest.loginWith
to login with any default user or user you have created with TestDataCreator
.
As we are using the @RightsAllowed
custom security annotation, user rights will be validated as-well, as long as you don't mock the CurrentUserService
.
Important to understand: Every call from a test method to a bean class or a class annotated with @TransactionalEjb
will be intercepted and start a transaction. Calls from such a method to another will keep the same transaction. When the call is finished the transaction will be committed and the entity manager will be cleared.
This means that within the test method itself no transaction is active by default. Use the AbstractBeanTest.executeInTransaction
method to wrap parts of your logic that need to be executed in one transaction.
The JPA part is build with hibernate-core
as JPA provider and h2database
as in-memory double for PostgreSQL.
Custom Postgres functions of SORMAS are provided in the H2Function class.
The database is automatically reset after every test method execution. See TestDatabaseCleaner
.
ArchUnit is used to enforce some architectural rules, e.g. making sure backend facades are correctly annotated in terms of user access checks.
Typcial ArchUnit use cases: Use Cases
Testcontainers is used to provide a throwaway instance of a postgres database for tests that can't be done on an in-memory h2 database.
This is currently used to test the history tables versioning trigger.