skip to content

In MockServer, what does connectionOptions().withCloseSocket(true) do to a bid reply?

level: juniorimportance: should knowfreq 50%

answer

  1. the reply arrives; the socket does not survive
  2. a response decoration, not an action
  3. one of eight ConnectionOptions settings
  4. withCloseSocketDelay controls the timing
  5. withDropConnection is not on this class

basics

~20 s

The reply is still written in full. MockServer then closes the socket rather than leaving it open for reuse. withCloseSocket is one of ConnectionOptions' eight settings, and it attaches to an HttpResponse, never to an error action.

solid answer

~40 s

`ConnectionOptions` is MockServer's way of shaping how a real reply is written, and you attach it with `response().withConnectionOptions(connectionOptions().withCloseSocket(true))`. The client still receives the whole response — status code, headers, body — and then finds the connection gone rather than available for the next call. Its sibling `withCloseSocketDelay` governs when that close lands relative to the reply. The full set of eight settings is `withSuppressContentLengthHeader`, `withContentLengthHeaderOverride`, `withSuppressConnectionHeader`, `withChunkSize`, `withChunkDelay`, `withKeepAliveOverride`, `withCloseSocket` and `withCloseSocketDelay`; `withDropConnection` is **not** among them, because dropping the connection means writing no reply at all and that is `HttpError`'s job. Reach for `withCloseSocket(true)` when the cattle-auction client should get a valid answer and only then hit a dead connection. If it should get no answer at all, that is a different action entirely and belongs to `HttpError`.

code

java · 14 lines
java
import static org.mockserver.model.ConnectionOptions.connectionOptions;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;

new MockServerClient("localhost", 1080)
    .when(request()
        .withMethod("GET")
        .withPath("/auctions/v1/lots/48/bids/current"))
    .respond(response()
        .withStatusCode(200)
        .withHeader("Content-Type", "application/json")
        .withConnectionOptions(connectionOptions()
            .withKeepAliveOverride(false)
            .withCloseSocket(true)));

go deeper

for a junior

Be ready to say that MockServer's withCloseSocket(true) still sends the whole reply and only then closes the connection. Name ConnectionOptions as the class it belongs to.

for a middle

Explain that ConnectionOptions attaches to an HttpResponse, so it can only decorate a reply that is being written. That is why withDropConnection cannot live there: it means writing nothing at all.

for a senior

Show which cattle-auction client behaviour this reaches that a dropped connection does not — connection reuse, and the code that runs after a bid response has been parsed successfully.

for a principal

Own the rule your teams follow for which MockServer surface a transport-failure stub uses, so a review can tell a deliberate socket close from a snippet copied without understanding.

## A reply that arrives, and a connection that does not survive it There are two quite different ways a stub server can be hostile. It can refuse to answer at all, or it can answer perfectly well and then take the connection away. `ConnectionOptions.withCloseSocket(true)` is MockServer's expression of the second. The bid reply is written in full — status code, headers, body — the client parses it successfully, and only then is the socket closed rather than left available for the next call. That distinction matters because it decides which client code you are testing. A client that never gets a reply exercises its exception handlers. A client that gets a good reply and then finds the connection gone exercises everything *after* a successful parse, plus whatever it does when it next tries to use that connection. ## Where ConnectionOptions attaches `ConnectionOptions` is not an action and cannot stand alone. It is a property of an `HttpResponse`, attached with `response().withConnectionOptions(connectionOptions()...)`, produced by the static factory `connectionOptions()`. Everything it can do therefore presupposes a reply that is being written. This single structural fact answers most questions people have about the class: - it cannot express "write nothing", because there is always a reply; - it cannot be used with `error(...)`, because an error action has no `HttpResponse` to decorate; - it takes effect after matching, at the moment the reply is serialised onto the socket. ## The eight settings, and what each family does `ConnectionOptions` has exactly eight `with*` settings, and they fall into three groups: - **How the length is declared** — `withSuppressContentLengthHeader`, `withContentLengthHeaderOverride`. - **How the reply is written out** — `withSuppressConnectionHeader`, `withChunkSize`, `withChunkDelay`, `withKeepAliveOverride`. - **Whether the connection survives** — `withCloseSocket`, `withCloseSocketDelay`. Only the last pair takes the connection away. The other six change what the client reads or how the bytes are framed, but leave it with something it can read to the end. If a colleague expects `withSuppressConnectionHeader(true)` to break a connection, that is the misunderstanding to correct: suppressing a header changes what the reply advertises, not what the socket does. ## withCloseSocket versus withDropConnection These two are constantly confused, and they are not on the same class. | call | class | reply written? | client sees | |---|---|---|---| | `withCloseSocket(true)` | `ConnectionOptions` | yes, in full | a good reply, then a dead connection | | `withDropConnection(true)` | `HttpError` | no | no bytes at all; a transport failure | The rule of thumb is simple: if a status code should still reach the client, you want `ConnectionOptions`; if it should not, you want `HttpError`. Anyone hunting for `withDropConnection` among the eight settings above will not find it, and that absence is by design rather than an oversight. ## When a cattle-auction test wants this shape Some realistic reasons to reach for `withCloseSocket(true)` on `GET /auctions/v1/lots/48/bids/current`: 1. The bidding client keeps connections around between polls, and you want the next poll to discover the connection is unusable rather than the current one to fail. 2. You are testing code that runs *after* a successful response — a cache write, a state transition, an event emitted — and you want to confirm it still happens when the connection is subsequently lost. 3. You want a failure the client's status handling cannot see, without giving up the ability to assert on the body that arrived first. In all three cases a dropped connection would be the wrong tool, because it destroys the reply you are relying on. ## The mistake to avoid, and how to write it so nobody makes it The single most common error is reaching for the wrong class, and it is easy to avoid by naming the class in the code and in the review comment: write `ConnectionOptions.withCloseSocket(true)` and `HttpError.withDropConnection(true)` in prose rather than the bare method names. The names are similar, both are genuine MockServer identifiers, and a search that only asks whether a method exists will happily approve a sentence that attaches it to the wrong class. For orientation, WireMock has no equivalent split: its transport failures all arrive through one decoration on the reply builder, `aResponse().withFault(...)`, so a reviewer moving between the two servers should expect the shape to change, not just the spelling.

  • In MockServer, when would you choose withCloseSocket(true) over error().withDropConnection(true)?
    When the client must receive a valid reply first. `withCloseSocket(true)` rides on an `HttpResponse`, so the bid answer is written and only the connection dies afterwards, which exercises connection reuse and everything that runs after a successful parse. `error().withDropConnection(true)` writes nothing, so the client never gets a response object at all.
  • In MockServer, which ConnectionOptions settings actually break the connection?
    Only `withCloseSocket` and `withCloseSocketDelay`. The other six — `withSuppressContentLengthHeader`, `withContentLengthHeaderOverride`, `withSuppressConnectionHeader`, `withChunkSize`, `withChunkDelay` and `withKeepAliveOverride` — change how the reply is declared or written but leave the client something it can read to the end. Do not expect any of them to produce a socket failure.

saying these in an interview costs you the question

  • Says withCloseSocket suppresses the response body
  • Looks for withDropConnection among ConnectionOptions' settings
  • Thinks ConnectionOptions can be used without a response
  • Confuses closing the socket with returning a 503
  • Assumes withSuppressConnectionHeader closes the connection