In MockServer, which class carries withDropConnection, and why is it not on ConnectionOptions?
answer
- an action, not a response decoration
- one expectation, exactly one action
- error() is the terminal factory
- HttpError owns the drop switch
- ConnectionOptions breaks it with withCloseSocket
basics
~20 sMockServer puts withDropConnection(Boolean) on HttpError, the terminal error action that replaces a reply entirely, not on ConnectionOptions. ConnectionOptions decorates a real response, and its connection-breaking switch is withCloseSocket(true). The probability variant, withDropConnectionProbability(Double), is on neither class: it lives on HttpChaosProfile.
solid answer
~50 sMockServer models a broken connection as an **action**, not as a decoration on a reply. `HttpError` comes from the static factory `error()`, and `withDropConnection(true)` on it tells the server to tear the socket down without writing a byte; you attach it with `when(request().withMethod("POST").withPath("/auctions/v1/lots/48/bids")).error(error().withDropConnection(true))`. Because `error(...)` is a terminal action, that expectation has no status code, no headers and no body. `ConnectionOptions` is a different kind of thing: it hangs off an `HttpResponse` via `withConnectionOptions(...)` and shapes a reply that is already being written. Its complete set of eight settings is `withSuppressContentLengthHeader`, `withContentLengthHeaderOverride`, `withSuppressConnectionHeader`, `withChunkSize`, `withChunkDelay`, `withKeepAliveOverride`, `withCloseSocket` and `withCloseSocketDelay`, so its connection breaker is `withCloseSocket(true)`. The probabilistic variant is on a third class again: `withDropConnectionProbability(Double)` belongs to `HttpChaosProfile`. Name the class beside the method, because all three names are real and only the class settles which is meant.
code
java · 21 linesimport static org.mockserver.model.ConnectionOptions.connectionOptions;
import static org.mockserver.model.HttpError.error;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
MockServerClient client = new MockServerClient("localhost", 1080);
// no reply at all: HttpError drops the socket
client.when(request()
.withMethod("POST")
.withPath("/auctions/v1/lots/48/bids"))
.error(error().withDropConnection(true));
// a real reply, then ConnectionOptions closes the socket
client.when(request()
.withMethod("GET")
.withPath("/auctions/v1/lots/48/bids/current"))
.respond(response()
.withStatusCode(200)
.withConnectionOptions(connectionOptions()
.withCloseSocket(true)));go deeper
Be ready to say that MockServer breaks a connection with error(), not with response(). Name HttpError as the class and withDropConnection(true) as the switch, and do not reach for a status code.
Explain why the switch cannot live on ConnectionOptions: that class decorates a reply being written, while a dropped connection writes no reply at all. Name a couple of the eight ConnectionOptions settings to show you know the difference.
Show you can pick the right surface for the client branch you want to exercise on a cattle-auction bid: no bytes at all, or a valid reply followed by a closed socket. Say which MockServer call produces each.
Own the argument for how far a stub estate should go in scripting socket-level failure, and where the probability-driven form on HttpChaosProfile stops being a repeatable test and starts being a chaos experiment.
## What a broken connection is, and why it is not a status code A stubbed status code, however unusual, still arrives as a well-formed HTTP message. The client's parser succeeds, a response object exists, and the branch that runs is the one that inspects a code. A broken connection produces no such object at all: the client's HTTP library raises whatever it raises for a socket that died, and the code that runs is the exception handler — the retry guard, the fallback, the circuit breaker. Those are usually written by different people at different times from the status-handling code, and only a transport-level surface reaches them. That is exactly why MockServer models a broken connection as a separate **action** rather than as a strange kind of response: it genuinely is a different thing happening. ## An expectation is a matcher plus exactly one action Every MockServer expectation is assembled the same way. `when(<request matcher>)` selects the traffic, and the chain it returns is completed by **one** action: - `respond(HttpResponse)` writes a real HTTP reply — status code, headers, body. - `forward(...)` sends the request onward to another host. - `error(HttpError)` acts on the transport underneath the reply; nothing HTTP is written. - the callback forms hand the request to your own code. That structure decides where the connection-breaking controls can live. "Drop the connection" is not a property of a reply, because in that case there is no reply. ## HttpError carries withDropConnection The class is `HttpError` and its static factory is `error()`. Its surface is small and worth memorising: - `error()` — the factory that starts one - `withDropConnection(Boolean)` — write nothing, tear the socket down - `withResponseBytes(byte[])` — write exactly these bytes, then close - `withStreamError(long)`, `withStreamError(StreamErrorCode)` and `withStreamErrorCodeName(String)` So a cattle-auction bid endpoint that must die on the wire is written as `client.when(request().withMethod("POST").withPath("/auctions/v1/lots/48/bids")).error(error().withDropConnection(true))`. The request still matches; it is the answer that never happens. ## ConnectionOptions decorates a reply that exists `ConnectionOptions` is a property of an `HttpResponse`, attached with `response().withConnectionOptions(connectionOptions()...)`. Because it can only exist beside a reply that is being written, it cannot express "write nothing". Its complete set of settings is eight: - `withSuppressContentLengthHeader` - `withContentLengthHeaderOverride` - `withSuppressConnectionHeader` - `withChunkSize` - `withChunkDelay` - `withKeepAliveOverride` - `withCloseSocket` - `withCloseSocketDelay` `withDropConnection` is **not** in that list, and looking for it there is the commonest mistake made about this API. What `ConnectionOptions` does offer is `withCloseSocket(true)`: the reply is written in full and the socket is then closed rather than left available, with `withCloseSocketDelay` governing when that close lands relative to the reply. ## The probability form lives on a third class There is a probabilistic variant, and it is on neither class above: `withDropConnectionProbability(Double)` belongs to `HttpChaosProfile`. This deserves saying out loud, because it is a correction to a correction. People who learn that `withDropConnection` is not on `ConnectionOptions` very often move the probability method onto `HttpError` in the same breath, and that is wrong too. | MockServer class | connection control | what the client sees | |---|---|---| | `HttpError` | `withDropConnection(true)` | no bytes at all; the socket dies | | `HttpError` | `withResponseBytes(byte[])` | your bytes, then a close | | `ConnectionOptions` | `withCloseSocket(true)` | the full reply, then a dead connection | | `HttpChaosProfile` | `withDropConnectionProbability(...)` | a proportion of connections dropped | ## Choosing the right surface, and naming it correctly 1. If the bidding client must take its transport-failure branch — the code that runs when there is no response object — use `error().withDropConnection(true)`. 2. If it must parse a valid bid response and only then find the connection gone, use `response().withConnectionOptions(connectionOptions().withCloseSocket(true))`. 3. If it must read something that is not valid HTTP at all, use `error().withResponseBytes(...)`. Both `withDropConnection` and `withCloseSocket` are real MockServer identifiers, so a search that only asks whether a name exists cannot tell a correct sentence from an incorrect one — only the class named beside the method carries the fact. The trap runs across products too: in WireMock the equivalent control is a decoration on the reply builder, `aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER)`, so a snippet copied from one server to the other is not merely differently spelled, it is differently shaped. Name the class as well as the method — `HttpError.withDropConnection(true)`, `ConnectionOptions.withCloseSocket(true)` — and the ambiguity disappears from your code review as well as from your answer.
- Where does MockServer's withDropConnectionProbability live, and why is that not HttpError?It is on `HttpChaosProfile`, not on `HttpError` and not on `ConnectionOptions`. `HttpError` describes one deterministic outcome for one matched request, so a probability has no meaning on it; the chaos profile is the surface that expresses "drop some proportion of connections". Moving the probability method onto `HttpError` is the second-order mistake people make right after learning the first one.
- How would you make a MockServer stub answer a bid normally and only then break the socket?Use a response, not an error action: `response().withStatusCode(200).withConnectionOptions(connectionOptions().withCloseSocket(true))`. The client parses a complete reply and then finds the connection gone. `error().withDropConnection(true)` cannot do this, because an error action writes no reply at all — the two exercise different client code.
saying these in an interview costs you the question
- Claims withDropConnection sits on MockServer's ConnectionOptions
- Thinks withDropConnectionProbability is a method on HttpError
- Attaches ConnectionOptions with no HttpResponse to decorate
- Expects a status code alongside a MockServer error() action
- Assumes suppressing Content-Length is enough to break the socket