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, DELETE for calendar resources
  • ETag-based conditional writes with If-Match / If-None-Match
  • PROPFIND for collection and resource property discovery
  • REPORT with calendar-multiget
  • REPORT with calendar-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

xml
<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.

java
@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; CalendarStore is 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.