Failure simulation
Production HTTP clients need more than happy-path JSON. Use these patterns to verify retries, backoff, timeouts, stream parsing, and fallback behavior.
Delayed response
Use delay when the server should accept the request but wait before sending the response.
1mokksy.get {
2 path("/slow")
3} respondsWith {
4 delay = 2.seconds
5 body = "eventually-ok"
6}1mokksy.get(spec -> spec.path("/slow"))
2 .respondsWith(response -> response
3 .delayMillis(2_000)
4 .body("eventually-ok"));Delayed chunks
Use delayBetweenChunks when the response should arrive incrementally and the client must process partial data.
1mokksy.get {
2 path("/slow-stream")
3} respondsWithStream {
4 delayBetweenChunks = 500.milliseconds
5 chunks += "first\n"
6 chunks += "second\n"
7}1mokksy.get(spec -> spec.path("/slow-stream"))
2 .respondsWithStream(stream -> stream
3 .delayBetweenChunksMillis(500)
4 .chunk("first\n")
5 .chunk("second\n"));Hanging request or stream
Use a stream that never completes when you need to verify client-side read timeouts, cancellation, or reconnect behavior.
1mokksy.get {
2 path("/never-finishes")
3} respondsWithSseStream {
4 flow = flow {
5 emit(ServerSentEvent(data = "started"))
6 awaitCancellation()
7 }
8}1mokksy.get(spec -> spec.path("/never-finishes"))
2 .respondsWithSseStream(stream -> stream
3 .chunks(Stream.generate(() -> SseEvent.data("heartbeat")))
4 .delayBetweenChunksMillis(1_000));Use this with a short client timeout to verify timeout handling.
Retry-after and rate limiting
Return 429 Too Many Requests with Retry-After when the client should back off and retry later.
1mokksy.post {
2 path("/payments")
3} respondsWith {
4 httpStatus = HttpStatusCode.TooManyRequests
5 headers += HttpHeaders.RetryAfter to "30"
6 body = """{"error":"rate_limited"}"""
7}1mokksy.post(spec -> spec.path("/payments"))
2 .respondsWith(response -> response
3 .status(429)
4 .header("Retry-After", "30")
5 .body("{\"error\":\"rate_limited\"}"));Malformed SSE
Send malformed event-stream data when you need to test parser failures and fallback behavior.
1mokksy.get {
2 path("/malformed-events")
3} respondsWithStream {
4 contentType = ContentType.Text.EventStream
5 chunks += "data: valid\n\n"
6 chunks += "this is not a valid event frame"
7}1mokksy.get(spec -> spec.path("/malformed-events"))
2 .respondsWithStream(stream -> stream
3 .contentType("text/event-stream")
4 .chunk("data: valid\n\n")
5 .chunk("this is not a valid event frame"));Partial failure
Send only part of the expected response when the client must handle incomplete transfers or timeout after partial data.
1mokksy.get {
2 path("/statement")
3} respondsWithStream {
4 chunks += "header\n"
5 chunks += "row-1\n"
6 delayBetweenChunks = 250.milliseconds
7}1mokksy.get(spec -> spec.path("/statement"))
2 .respondsWithStream(stream -> stream
3 .chunk("header\n")
4 .chunk("row-1\n")
5 .delayBetweenChunksMillis(250));Keep the client timeout lower than the full expected transfer time to verify partial-data handling.