Skip to content
axxbetadocs
nextv0.2.26
GitHub
These are the docs of main, not released yet. See the docs of v0.2.26, the latest release.

Seed and query MongoDB

View .mdOpen in Claude

The MongoDB steps put documents in place before your service reads them, and check the documents it writes.

Background:
Given a tracking-db mongo database with the following properties:
| url | mongodb://localhost:27017/parcels?authSource=admin |
| user | parcels |
| password | parcels |

All three properties are required and support ${env:...} and ${sys:...}. The URL must include the database name; authSource defaults to it. The first MongoDB database registered in a scenario is the default.

A seed is a JSON object that maps collection names to arrays of documents. Extended JSON ({"$oid": "..."}, {"$date": "..."}) is supported:

seeds/scans-in-transit.json
{
"scans": [
{
"scanId": "SC-3001-2",
"parcelRef": "PX-TRK-3001",
"status": "IN_TRANSIT",
"location": "Hamburg hub",
"scannedAt": {"$date": "2026-05-05T06:40:00Z"}
},
{
"scanId": "SC-3001-1",
"parcelRef": "PX-TRK-3001",
"status": "PICKED_UP",
"location": "Berlin depot",
"scannedAt": {"$date": "2026-05-04T16:10:00Z"}
}
]
}
Scenario: Tracking shows the latest scan, however the scans arrive
Given a seeds/scans-in-transit.json mongo db seed
And within 10s a selection of at least 1 document is retrieved from the tracking collection where:
| _id | PX-TRK-3001 |
| scanCount | 2 |
When a GET request to /api/parcels/PX-TRK-3001/tracking
And the request is executed
Then the response status code is 200
And the response payload properties are:
| status | IN_TRANSIT |
| lastLocation | Hamburg hub |
| scanCount | 2 |

The service builds its tracking summaries from the scans in the background, so the scenario waits for the summary before it calls the API.

To seed a specific database when the scenario registers more than one:

Given a seeds/scans-in-transit.json MongoDB seed for tracking-db

a seeds/scans-in-transit.json mongo db seed for tracking-db is the same step with the other spelling.

The file path resolves against the resources directories in axx.yaml. See the mongo pack reference.

A document selection finds documents with equality conditions. Dotted field paths reach into nested documents, and the mongo pack reference says how values are read:

Then a selection of documents is retrieved from the scans collection where:
| parcelRef | PX-TRK-3001 |
| status | PICKED_UP |
And the selection has 1 document
And the 1st document for the selection properties are:
| scanId | SC-3001-1 |
| location | Berlin depot |
| scannedAt | 2026-05-04T16:10:00.000Z |

Properties are JSONPaths (location, history[0].status), compared as text; null means null and undefined means the field is absent (the rules). the 1st document for the selection properties match: takes Java regular expressions instead.

Selections are numbered in the order a scenario retrieves them, and a step without an ordinal checks the first. After a second retrieval (the tracking view before and after a scan, say), name the one a step checks: the 1st document for the 2nd selection properties are:. axx validate warns about a step that checks the first while a later selection goes unchecked.

Like the SQL selections, they are numbered in the order they are retrieved (the 2nd selection has 3 documents), and has more than / has fewer than compare counts.

Then within 10s a selection of at least 1 document is retrieved from the tracking collection where:
| _id | PX-TRK-3001 |
| scanCount | 2 |

The step polls every 500 ms until enough documents match, and fails when the time runs out with fewer. The documents it found are the selection, for later steps to check (the selection has 1 document, or its properties). Values that parse as JSON are typed, so 2 matches the number 2.

Every query step has an on <service> form for scenarios with more than one MongoDB database.

Seeded documents stay in the database after the scenario, and scenarios run in parallel. Give each scenario’s documents their own keys (PX-TRK-3001 above) and query by them. Scenario isolation explains the approach.