In Mountebank, which behavior makes a stubbed response slow, and how is it declared?
answer
- mountebank calls them behaviors
- the list is closed at five
- mountebank wait sits in behaviors array
- milliseconds, or a function with injection
- repeat is a response field, not one
basics
~20 sMountebank's wait behavior makes a response slow. It is one of Mountebank's five behaviors and is declared as an entry in the behaviors array on a response, taking a number of milliseconds. Repeat is not a behavior.
solid answer
~40 sMountebank's `wait` behavior makes a response slow. It is one of Mountebank's five behaviors — `wait`, `copy`, `lookup`, `shellTransform` and `decorate` — and it is declared as an entry in the `behaviors` array on a **response** object, beside the response type (`is`, `proxy`, `inject` or `fault`). The value is normally a number of milliseconds; if it does not parse as an integer, Mountebank evaluates it as a JavaScript function returning milliseconds, which needs the server started with `--allowInjection`. Mountebank's `wait` holds the whole response back, so nothing reaches the client until it has elapsed. Note that `repeat` is **not** a Mountebank behavior — it is a field on a response controlling how many times that response is served. WireMock expresses the same idea as `aResponse().withFixedDelay(2000)` on the stub's response definition.
go deeper
Know that Mountebank calls its response post-processing steps behaviors, and that wait is the one that adds latency. Be able to say it takes a number of milliseconds.
Be ready to name all five Mountebank behaviors and to place wait in the behaviors array on a response, beside the response type. Know that repeat is a response field rather than a behavior.
Show that you know Mountebank's wait accepts a JavaScript function returning milliseconds only when the server runs with --allowInjection, and that it holds the whole response back rather than trickling it out.
Be able to compare the three servers' latency surfaces honestly, and say what a team gives up by standardising on Mountebank's single wait value rather than on a server offering named distributions.
Mountebank's model is different in shape from a Java DSL. A Mountebank imposter is a JSON document, a stub inside it holds an array of responses, and a Mountebank response may carry behaviors that post-process it before it is sent. Latency is one of those Mountebank behaviors, and knowing which one it is — and which convincing look-alike is not a behavior at all — is the whole of this question. The vocabulary is small and closed, which makes it easy to learn and easy to get subtly wrong. ## Where wait sits among Mountebank's behaviors Mountebank has exactly five behaviors, and the list is closed: - Mountebank's `wait` — hold the response back before sending it. - Mountebank's `copy` — take a value out of the request and substitute it into the response. - Mountebank's `lookup` — take a value out of the request and use it as a key into an external data source. - Mountebank's `shellTransform` — pipe the response through an external command. - Mountebank's `decorate` — post-process the response with a JavaScript function. Only Mountebank's `wait` concerns latency. It is declared as an entry in the `behaviors` array on a response object, sitting beside the response type — Mountebank's response types are `is`, `proxy`, `inject` and `fault` — so a slow reply on a fitting imposter reads roughly `{ "is": { "statusCode": 200 }, "behaviors": [ { "wait": 2000 } ] }`. Because a Mountebank behavior belongs to the response rather than to the stub or the imposter, two responses inside one Mountebank stub may wait different amounts. A Mountebank imposter for `POST /fitting/sessions` can answer the first call after two seconds and the next one immediately, simply by giving the two responses different `behaviors` arrays. That is the granularity to reach for when a test needs one slow call followed by a fast one rather than a uniformly slow endpoint. ## What wait accepts, and what it does - Mountebank's `wait` normally takes a number of milliseconds, written as a plain integer. - If the value does not parse as an integer, Mountebank treats it as a JavaScript function returning the number of milliseconds and evaluates it, which requires the server to have been started with `--allowInjection`. - Mountebank's `wait` holds the entire response: nothing is written to the client until the wait has elapsed, so it is the "slow to answer" instrument and not a "slow to transfer" one. - Where WireMock offers separate `withUniformRandomDelay(` and `withLogNormalRandomDelay(` methods, Mountebank's `wait` is a single value, and any spread has to come from its function form under `--allowInjection`. Mountebank applies behaviors to a response after it has been resolved, so `wait` delays the *sending* rather than the *producing*. That is why it reads the same whether the response it slows is a canned `is` body or something a `proxy` fetched from a real upstream: in both cases Mountebank has the finished response in hand and simply holds it. ## Choosing a Mountebank wait on a fitting imposter 1. Put the Mountebank `wait` on the specific response you want slow — the `GET /fitting/patients/{patientId}/audiogram` response standing in for an overloaded records service — rather than on every response the imposter is able to give. 2. Keep the value a plain integer unless you genuinely need variation. Mountebank's function form works only under `--allowInjection`, which is a server-wide decision with consequences reaching well beyond one wait. 3. Where you need one slow call followed by a fast one, use two entries in the stub's `responses` array with different `behaviors`, rather than trying to make a single Mountebank `wait` conditional. ## Why repeat is not a behavior The commonest Mountebank mistake is listing `repeat` among the behaviors. In Mountebank, `repeat` is a **field on a response**, not a behavior: it says how many times that response is served before the imposter advances to the next entry in the stub's `responses` array, and Mountebank's validation requires it to be an integer greater than zero. In Mountebank it controls *sequence*, not *timing*, and it does not live inside the `behaviors` array. Confusing the two produces a Mountebank imposter that validates happily and then does something other than what its author meant. ## The same idea in the other two servers | Product | How a slow reply is declared | |---|---| | Mountebank | a `wait` entry in the response's `behaviors` array | | WireMock | `aResponse().withFixedDelay(2000)` on the stub's response definition | The vocabularies do not cross. In MockServer the equivalent is `withDelay(Delay.milliseconds(2000))` on the expectation's response. ## Mistakes worth naming - Listing `repeat` as one of Mountebank's behaviors. In Mountebank it is a response field; the behaviors are `wait`, `copy`, `lookup`, `shellTransform` and `decorate`. - Putting a Mountebank `wait` on the stub or the imposter instead of on an individual response. - Expecting Mountebank's function form of `wait` to work on a server started without `--allowInjection`. - Assuming a Mountebank `wait` dribbles the body out slowly; it holds the whole response and then sends it in one piece. - Writing WireMock's `withFixedDelay(` name into a Mountebank imposter, or Mountebank's `wait` key into a WireMock mapping.
- How do you give two calls to the same Mountebank stub different waits?Put two responses in the Mountebank stub's `responses` array and give each its own `behaviors` array. Mountebank cycles through the responses in order, so the first call gets the first response's `wait` and the second call gets the next one's. A behavior belongs to a response rather than to the stub, which is what makes this possible.
- What does Mountebank's repeat field do, if it is not a behavior?It says how many times that response is served before Mountebank advances to the next entry in the stub's `responses` array, and its validation requires an integer greater than zero. In Mountebank it controls sequence rather than timing, and it lives on the response itself rather than inside the `behaviors` array.
saying these in an interview costs you the question
- Lists repeat among Mountebank's five behaviors
- Puts a Mountebank wait on the imposter, not a response
- Expects Mountebank's function form of wait without --allowInjection
- Thinks a Mountebank wait dribbles the body out slowly
- Uses WireMock's withFixedDelay name inside a Mountebank imposter