skip to content

Mock Mode

Karate can serve a feature file as a live HTTP server instead of calling one, so the same syntax that tests an API also fakes it. Interviewers probe how far that stand-in really goes.

on this pageshow

explore

questions

16

In a Karate mock feature - the kind served by `karate.start()` or a `MockServer` - when do the `Background` steps run?

level: juniorimportance: must knowfreq 70%

answer

  1. Count executions, not scenarios
  2. Server lifetime, not request lifetime
  3. The opposite of a normal feature file
  4. Runs during construction, before listening

basics

~20 s

Once, when the mock server starts. Karate executes a mock feature's Background while the handler is being built, before the first request arrives; every request afterwards runs only the steps of the one Scenario whose name matched.

solid answer

~50 s

Karate runs a mock feature's `Background` **exactly once**, while the mock handler is being constructed and before the server is listening. Whatever it defines is copied into the handler's global variable map, and every later request starts from that map. A request then executes only the steps of the `Scenario` whose name expression matched - the `Background` steps are **not** prepended to it. That is the opposite of a normal Karate test feature, where `Background` re-runs ahead of every scenario, and the asymmetry is exactly why a Karate mock is stateful by default: `* def cats = {}` in the `Background` is **one** map that lives as long as the server, not a fresh empty map per call. Anything that must happen per request belongs in the matched `Scenario`, or in a `configure afterScenario` hook.

code

gherkin · 16 lines
gherkin
Feature: stateful cats mock

Background:
  # runs ONCE, when the mock server starts
  * def uuid = function(){ return java.util.UUID.randomUUID() + '' }
  * def cats = {}

Scenario: pathMatches('/cats') && methodIs('post')
  * def cat = request
  * def id = uuid()
  * cat.id = id
  * cats[id] = cat
  * def response = cat

Scenario: pathMatches('/cats')
  * def response = $cats.*

go deeper

for a junior

Hold on to the one sentence: in mock mode the Background runs once at start-up, not before each request. That single fact explains why a Karate mock can hold data at all.

for a middle

Be able to say where those Background variables go - into the handler's global map - and that a request executes only the matched Scenario's own steps, never the Background's.

for a senior

Know what it means operationally: the mock's data is server-lifetime state shared by every client, so a test that mutates it changes what the next test sees.

for a principal

Weigh the convenience of a long-lived stateful mock against the coupling it creates between the tests that share it, and decide who owns that state and who is allowed to reset it.

## Two lifecycles behind one keyword `Background` means two different things in Karate, depending on which mode the feature is running in. In an ordinary test feature it is **per-scenario setup**. Karate builds each scenario's step list by prepending the feature's `Background` steps to the scenario's own, so a feature with five scenarios executes its `Background` five times, and each scenario begins from an identically fresh evaluation of it. In **mock mode** - a feature served by `karate.start(...)` or by a `MockServer` - the same keyword is the **server's start-up block**. The mock handler reads the `Background` once while it is being constructed, executes its steps, and never looks at them again. A request handled later executes only the steps that belong to the matched `Scenario`; the `Background` steps are not part of that step list at all. ## What "once" means mechanically The order is worth holding in your head, because several of mock mode's other surprises fall straight out of it: 1. Karate parses the mock feature and creates a runtime for it. 2. It registers the mock helper functions - `pathMatches`, `methodIs`, `bodyPath` and friends - so the `Background` can already refer to them. 3. It executes every `Background` step, in order, **once**. 4. It copies the variables the `Background` left behind into the handler's global map. 5. Only then does the server bind a port and start accepting connections. Because step 3 happens before step 5, a `Background` step that fails takes the whole server down at start-up rather than producing a failing response. Because step 4 copies into a map that outlives a request, `* def cats = {}` really is a single map for the life of the server. ## Why Karate does it this way A mock feature is not a test. Its `Scenario` blocks are not cases to be run top to bottom; each one is a **request matcher** whose name is a JavaScript expression, and exactly one of them handles any given request. Re-running `Background` before each of them would be meaningless - there is no "next scenario" being prepared - and actively harmful, because it would wipe the in-memory store on every call and make a stateful mock impossible to write. Karate leans on that deliberately: the recommended way to model an API that remembers things is a plain object created in the `Background` and mutated by the Scenarios. ## Mock mode versus test mode at a glance | | Test feature | Mock feature | |---|---|---| | `Background` runs | before every `Scenario` | once, at server start | | A `Scenario` is | a test case | a request matcher | | The `Scenario` name is | a free-text label | a JavaScript match expression | | Variables after a `Scenario` | discarded with the scenario | written back to the server's globals | | Nothing matches | not applicable | the request gets HTTP 404 | ## What belongs in a mock Background Good candidates, all of them start-up shaped: - **Seed state** - `* def cats = {}`, or a fixture loaded with `read()`. - **Helper functions** the Scenarios will call: a key generator, a formatter, a clock. - **`configure` steps** that set behaviour for every response the server will ever send. - **A per-request hook declared once** - `* configure afterScenario = function(){ ... }`, where the declaration runs once but the function is invoked per request. Bad candidates, because they will happen exactly once and then never again: - Reading anything off the current request. There is no request yet when `Background` runs. - Resetting a counter or clearing a store "between calls". - Anything you expect to see in the log once per client. ## The trap this sets The failure is quiet, which is why interviewers ask. Someone writes a mock whose `Background` loads a fixture and whose Scenario mutates it; the first test passes and the second fails on data the first one left behind. Nothing errored - the mock simply remembered. The fix is to decide deliberately where a reset lives, rather than assuming the `Background` provides one. The mirror-image trap is expecting freshness and getting staleness: `* def now = ...` in the `Background` freezes one timestamp at start-up, and every response for the rest of the run carries it. One last scope note: those `Background` variables become the handler's **globals**, and globals are shared by every client of that server. There is no per-connection or per-client copy. Whatever one caller writes, the next caller reads.

  • In a normal, non-mock Karate feature, how often does `Background` run?
    Before every `Scenario`. Karate builds each scenario's step list by prepending the feature's `Background` steps to it, so each scenario starts from a fresh evaluation. Mock mode is the exception: the handler reads the `Background` once at construction, and a matched scenario runs only its own steps.
  • You need something to happen on every request to a Karate mock. Where do you put it?
    In the matched `Scenario`'s own steps, or in a `configure afterScenario = function(){ ... }` declared in the `Background`. The `configure` step itself still runs only once - it just stores the function - but the handler invokes that function after the matched scenario on every request.
  • Does a mock feature's `Background` see variables from `karate-config.js`?
    No. A mock feature is initialised without the suite that loads the config chain, so none of it applies. If you genuinely need those values, load the file explicitly from the `Background` with a `call read(...)` step, which is the documented workaround.

Read a mock feature as a small class: the Background is its constructor and each Scenario is a request-handling method. The constructor runs when the object is created; the handlers run once per call.

saying these in an interview costs you the question

  • Says Background re-runs before every mock request
  • Expects a fresh empty store on each call
  • Thinks each request gets its own isolated variable scope
  • Puts per-request setup steps in the mock Background
  • Assumes karate-config.js seeds a mock feature
open as a page

In a Karate mock feature file, what is the text after `Scenario:` used for, and what does the mock return when no `Scenario` matches the incoming request?

level: juniorimportance: must knowfreq 66%

basics

~20 s

In a Karate mock feature the Scenario name is a JavaScript expression evaluated per request, not a label. Scenarios are tried in file order; the first one returning true answers, and if none does the mock replies 404.

open as a page

In a Karate mock feature file, how does a matched Scenario produce the HTTP reply — what do you write instead of returning a response object?

level: juniorimportance: must knowfreq 72%

basics

~10 s

A mock scenario returns nothing. It assigns ordinary variables — response, responseStatus, responseHeaders, responseDelay — and after the last step Karate reads them and assembles the reply, so declaration order does not matter.

open as a page

A Karate mock feature has to remember data between HTTP requests. Where does that state live, and what puts it there?

level: middleimportance: must knowfreq 60%

basics

~20 s

In a map of global variables owned by the mock handler. The Background seeds it once at start-up, and after every matched Scenario the handler copies that request's variables back, so a def inside a Scenario survives too.

open as a page

In a Karate mock feature, what does `Scenario: pathMatches('/cats/{id}')` match, and where does the `id` value become available?

level: middleimportance: must knowfreq 58%

basics

~20 s

It matches a request path of exactly two segments whose first is literally cats, capturing the second under the name id. On a successful call the helper fills the pathParams map, so the scenario body reads pathParams.id as a string.

open as a page

In a Karate mock feature, what do configure responseHeaders and configure cors = true in the Background do to every reply, and how does a scenario's own responseHeaders interact with them?

level: middleimportance: must knowfreq 54%

basics

~20 s

Both are server-wide and belong in the Background. configure responseHeaders gives every successfully served reply a header map; configure cors = true answers OPTIONS preflights and adds Access-Control-Allow-Origin. A scenario's own responseHeaders merges over that map, key by key.

open as a page

Which built-in helper functions can the `Scenario` name of a Karate mock feature call, and what do you do when none of them expresses the match you need?

level: juniorimportance: should knowfreq 44%

basics

~20 s

Karate puts eight helpers in scope for a mock scenario name: pathMatches, methodIs, typeContains, acceptContains, headerContains, paramValue, paramExists and bodyPath. The name is JavaScript, so when none fits you write an expression over the request variables.

open as a page

A step in a Karate mock feature's `Background` fails. Does the mock server still come up, and what does a client see?

level: middleimportance: should knowfreq 38%

basics

~20 s

It does not come up. The Background runs inside the mock handler's construction, before any port is bound, so a failed step throws out of the start call. A client gets a connection refusal, not an HTTP status.

open as a page

Inside a Karate feature file, what does `karate.start('cats-mock.feature')` return, and how long does the mock it starts stay alive?

level: middleimportance: should knowfreq 34%

basics

~20 s

A MockServer object, Karate's own handle on the running mock. The mock's Background has already run by the time the call returns. Read .port off it for the port actually bound; it serves until stopped or the JVM exits.

open as a page

A Karate mock feature's `Background` runs only once, at server start. How do you get a hook that runs on every request instead?

level: middleimportance: should knowfreq 34%

basics

~20 s

Declare configure afterScenario = function(){ ... } in the mock feature's Background. The configure step itself runs once and merely stores the function; the handler then invokes it after the matched Scenario on every request.

open as a page

A Karate mock has `Scenario: pathMatches('/cats') && paramValue('type')`, but a request to `/cats?type=tabby` falls through to the catch-all instead. Why?

level: middleimportance: should knowfreq 40%

basics

~20 s

The expression evaluates to the string tabby, not to true. A Karate mock selects a scenario only when its name evaluates to a real boolean true, so a truthy string is a non-match. Compare the value instead, or use paramExists.

open as a page

In a Karate mock feature, what does karate.proceed('http://backend:8080') do to the incoming request, and what can the scenario still do to the reply that comes back?

level: middleimportance: should knowfreq 46%

basics

~20 s

karate.proceed forwards the request the mock is handling to the base URL you give it and brings the real reply back into the scenario, where it can still be changed before the caller ever sees it.

open as a page

Two clients hit a stateful Karate mock at the same moment. Does the mock handler run their matched Scenarios concurrently?

level: seniorimportance: should knowfreq 32%

basics

~10 s

No. Karate's mock handler serialises request handling - one request at a time goes through matching and step execution, whatever the server's threads are doing - because the retained globals are shared mutable state.

open as a page

You add a `Scenario Outline` with an `Examples:` table to a Karate mock feature so one block can serve several paths, and it never answers a request. What is happening?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Scenario Outline is not supported in Karate mock mode. While looking for a match the handler skips an outline section with a warning, so the block never replies. Write the routes out, or move the variation into one scenario's body.

open as a page

A Karate 2.x mock builds its reply with a Background helper * def uuid = function(){ return java.util.UUID.randomUUID() + '' } copied from the mock documentation. The server starts, but every request to the scenario that uses it returns 500. Why?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Karate 2.x turns Java interop off by default inside a mock feature. Defining the function touched no Java, so the server started; the first call evaluates java.util.UUID with no bridge behind it, the step fails, and the mock answers 500.

open as a page

In a Karate mock feature, how do you make one endpoint answer three seconds late, and why is that better than sleeping inside the scenario?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Set the variable: a step reading def responseDelay = 3000 in that scenario. The mock handler serialises requests, so sleeping inside a scenario stalls every other client, while responseDelay is applied by the server after the handler has already returned.

open as a page