A small, embeddable CalDAV server built for one purpose: making calendar-client tests deterministic, fast and inspectable. When you need a real CalDAV endpoint to drive your TDD cycle but a full external calendar server would add too much noise, this is what you reach for.
What it implements
A focused subset of RFC 4791:
PUT,GET,DELETEfor calendar resources- ETag-based conditional writes with
If-Match/If-None-Match PROPFINDfor collection and resource property discoveryREPORTwithcalendar-multigetREPORTwithcalendar-query, including time-range filtering- basic recurrence expansion for query matching
- XML hardening, request body limits, structured XML error responses
It does not try to be a complete CalDAV server. Intentionally unsupported behaviour should make your test contracts visible — that’s the whole point.
Why a separate testbench?
Tests that hit a shared calendar server are flaky by construction: state bleeds between runs, schemas evolve, networks twitch. Tests that mock the HTTP layer miss the actual protocol semantics — exactly where CalDAV bugs hide.
CalDAV Testbench sits in the middle: real HTTP, real CalDAV semantics, in-memory state. The server boots on an OS-assigned port, lives for the test’s lifetime, and goes away clean.
Usage in JUnit
<dependency>
<groupId>com.svenruppert</groupId>
<artifactId>caldav-testbench</artifactId>
<version>00.10.00</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.svenruppert</groupId>
<artifactId>caldav-testbench</artifactId>
<version>00.10.00</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>The test-jar adds CalDavExtension — a JUnit Jupiter extension that
manages server lifecycle.
@ExtendWith(CalDavExtension.class)
class MyCalendarClientTest {
@Test
void uploadsAndFetchesEvent(CalDavServer server) {
var url = server.collectionUrl("svenr");
// drive your CalDAV client against this URL...
}
}Typical use cases
- TDD a calendar client — write the test, then implement the request
- Validate sync code against known server behaviour (ETag races, etc.)
- Verify request generation for the full CalDAV verb set
- Reproduce edge cases without depending on a shared external service
- Keep test fixtures close to the code that uses them
Tech stack
- JDK 26 built-in
com.sun.net.httpserver.HttpServer(no Jetty, no Netty) - Biweekly for iCalendar parsing
- In-memory store by default;
CalendarStoreis a documented extension point - Built and tested with Maven 4 via wrapper
A young project (June 2026) that came out of needing exactly this for other calendar work — not yet at 1.0, but actively used.