Testing
The extension supports two complementary test strategies that can be used side by side in the same test suite.
| Strategy | MongoDB | Startup speed |
|---|---|---|
Dev Services (automatic container) |
real MongoDB in Docker |
slower (container pull + boot) |
|
in-process, no Docker |
fast (JVM only) |
Dev Services (automatic MongoDB container)
When morphium.hosts is not set, the extension starts a MongoDB container automatically
in test mode.
No configuration is required:
@QuarkusTest (1)
class ProductRepositoryTest {
@Inject ProductRepository repository;
@Inject Morphium morphium;
@BeforeEach
void setUp() {
morphium.dropCollection(ProductEntity.class);
morphium.ensureIndicesFor(ProductEntity.class);
}
@Test
void savePersistsEntity() {
var product = new ProductEntity();
product.setName("Widget");
var saved = repository.save(product);
assertThat(saved.getId()).isNotNull();
}
}
| 1 | Dev Services automatically starts a MongoDB container – nothing else needed. |
To customise the container image:
# src/test/resources/application.properties
%test.quarkus.morphium.devservices.image-name=mongo:7
InMemDriver (no Docker)
For tests that should run without Docker, Morphium’s built-in InMemDriver processes all
operations inside the JVM.
The quarkus-morphium-testing artifact ships a ready-made Quarkus test profile that sets
the required configuration overrides.
Dependency
Add quarkus-morphium-testing as a test dependency:
<dependency>
<groupId>io.quarkiverse.morphium</groupId>
<artifactId>quarkus-morphium-testing</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
Usage
import de.caluga.morphium.quarkus.testing.InMemMorphiumTestProfile;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
@QuarkusTest
@TestProfile(InMemMorphiumTestProfile.class) (1)
class ProductRepositoryInMemTest {
@Inject ProductRepository repository;
@Inject Morphium morphium;
@BeforeEach
void setUp() {
morphium.dropCollection(ProductEntity.class);
morphium.ensureIndicesFor(ProductEntity.class);
}
@Test
void savePersistsEntity() {
var product = new ProductEntity();
product.setName("Widget");
var saved = repository.save(product);
assertThat(saved.getId()).isNotNull();
}
}
| 1 | All Morphium operations run in-process; no container is started. |
InMemMorphiumTestProfile applies the following configuration overrides:
morphium.driver-name=InMemDriver
morphium.database=inmem-test
quarkus.morphium.devservices.enabled=false
What the InMemDriver supports
The in-memory driver is a full implementation of the Morphium driver interface. It supports:
-
CRUD operations (
store,delete, query) -
Index creation via
ensureIndicesFor(no-op, always succeeds) -
Collection management (
dropCollection,clearCollection) -
Transactions (best-effort – no multi-document atomicity)
-
@Versionoptimistic locking
|
The
|
Mixing Both Strategies
Dev Services tests and InMemDriver tests coexist without any extra configuration.
Quarkus detects the different @TestProfile on the InMemDriver test classes and
restarts the application context once when switching between profiles.
All other tests in the same profile group share a single context and start up only once.
ProductRepositoryTest → @QuarkusTest → shared Dev Services context
ProductServiceTest → @QuarkusTest → shared Dev Services context
ProductRepositoryInMemTest → @TestProfile(InMemMorphiumTestProfile.class) → separate InMem context
CampaignRepositoryInMemTest → @TestProfile(InMemMorphiumTestProfile.class) → same InMem context (reused)
The trade-off: InMem tests run faster individually but incur a one-time restart cost when the test runner first encounters the profile. Use InMem tests for pure repository / persistence-layer tests and Dev Services tests for integration tests that require real MongoDB behaviour (e.g. aggregations, TTL indexes).
Test Isolation
Both strategies use the same isolation pattern: drop the collection and recreate indexes before each test.
@BeforeEach
void setUp() {
morphium.dropCollection(MyEntity.class); (1)
morphium.ensureIndicesFor(MyEntity.class); (2)
}
| 1 | Removes all documents and the collection itself. |
| 2 | Re-creates declared indexes – important for unique-constraint tests. |
Alternatively, use morphium.clearCollection(MyEntity.class) to delete all documents
while retaining the collection and its indexes (faster when index creation is expensive).
Testing Transactions
@MorphiumTransactional requires a replica set. The InMemDriver does not provide true
multi-document atomicity, so transaction tests must use Dev Services (replica set is enabled
by default — no extra configuration needed).
@QuarkusTest
class OrderServiceTransactionTest {
@Inject OrderService orderService;
@Inject Morphium morphium;
@BeforeEach
void setUp() {
morphium.dropCollection(Order.class);
morphium.dropCollection(Payment.class);
}
@Test
void commitOnSuccess() {
orderService.placeOrder(new Order("A1"), new Payment(42.0));
assertThat(morphium.createQueryFor(Order.class).countAll()).isEqualTo(1);
}
@Test
void rollbackOnFailure() {
assertThrows(RuntimeException.class, () ->
orderService.placeOrderThatFails(new Order("A2"), new Payment(0.0)));
assertThat(morphium.createQueryFor(Order.class).countAll()).isEqualTo(0);
}
}
See Transactions for details on the transaction lifecycle.
Integration Tests
For @QuarkusIntegrationTest (tests running against the packaged application), Dev Services
are still available. The container started during the build phase is reused:
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
class ProductResourceIT {
@Test
void listProductsReturnsOk() {
given()
.when().get("/products")
.then().statusCode(200);
}
}
For a complete example of integration tests with the Morphium extension, see the quarkus-morphium-showcase project.
InMemDriver Limitations Reference
| Feature | Supported | Notes |
|---|---|---|
CRUD ( |
yes |
Full support |
Index creation ( |
yes |
No-op, always succeeds |
Collection management ( |
yes |
Full support |
|
yes |
Full support |
Simple aggregations ( |
partial |
Basic stages only |
Complex aggregations ( |
no |
Use Dev Services for these tests |
Geospatial queries |
no |
Use Dev Services |
Multi-document transactions |
best-effort |
No true atomicity — use Dev Services (replica set enabled by default) |
Change streams |
no |
Use Dev Services |