Test Tools Safely with Mocks

Open in CMS

Once your agent calls tools (your own API, an MCP server, another agent or a plugin), testing gets harder: a test run could read live data that changes every day, write to a real system, or fail because a service is down. Mocks fix that. In this step you write scripted answers for your tools, attach them to a conversation simulation, and run it, so every run gets the same predictable tool results and nothing real is touched.

In this tutorial you test how Atlas, Kirana Group's operations assistant, reports project status. Atlas looks up projects with the Custom API get_project_status from Connect Your API. The real project data changes as work moves on, so you pin it down with a mock set: KG-2041 is always On hold at the CFO stage, and every other code returns 404 Not Found. Then you run a two-step simulation against it.


Before you start


Why use mocks

During a simulation, every tool call goes through a gate that decides what happens to it. Without mocks, each kind of tool has a fixed default:

ToolDefault in a simulation (no mock)
Custom API, MCP server, other agents and A2A peersBlocked: no call is made and the agent gets a policy error instead of a result.
Plugins that read data (for example Dynamic Table or Public Documents)Live: the real call runs and returns real data.
Plugins and built-in tools that write data (forms, reminders, escalation)Simulated: no real call; the agent gets an empty "success" answer.
Web search and web scrapingLive, and they cannot be mocked.

So without mocks, a scenario that depends on Atlas's Projects API can never pass, and a scenario that reads a live table can pass today and fail tomorrow. A mock gives the tool a scripted answer instead. That lets you:

  • Test without touching real systems or real data. No real project records, no writes to a production system, no calls to a paid API.
  • Get the same result on every run, so a failing run means the agent changed, not the data.
  • Test the hard paths on purpose: an empty result, a "not found", a 500 error, a timeout, a project that is on hold. These are difficult to trigger with a real service.

Key terms

TermMeaning
Mock setA named collection of scripted answers for one or more tools. Library sets are shared and can be reused by any conversation simulation of the agent.
Tool mockThe part of a mock set for one tool.
CaseOne scripted answer for a tool, used when the call's arguments match the case's conditions. A tool can have up to 50 cases, checked from top to bottom.
ConditionA rule on one argument of the call, such as projectCode is KG-2041. All conditions of a case must hold.
OtherwiseWhat a tool answers when no case matches: a default response, or "keep looking" in the next mock set.

Step 1: Create a mock set

  1. In the CMS, open Simulation → Mocks in the agent sidebar. The page is titled Tool Mocks.

  2. Click New Mock Set.

  3. Fill in the set:

    FieldValue for Atlas
    Name (required, up to 120 characters)Projects API: KG-2041 on hold
    Descriptionget_project_status returns a fixed "On hold" answer for KG-2041 and 404 for any other code.
Mock set editor titled Projects API: KG-2041 on hold with the Library chip, Used in 0 conversations, Duplicate and Save buttons, the Name and Description fields, the Tools in this set list with get_project_status (Custom API, 1 case, default) and the Add tool button, and the card for get_project_status (Custom API, GET) with its description

The Library chip next to the title means this set is shared: you can attach it to any conversation simulation of this agent. Used in 0 conversations changes once you attach it in Step 6. Duplicate makes a copy of the whole set.


Step 2: Add the tool you want to mock

  1. Under Tools in this set, click Add tool.
  2. Search for get_project_status and click it. The list shows the tools of the published agent, grouped by source (Custom API, MCP, Plugins, Built-in). Each entry shows what the tool does with data and what it would do in a simulation if you don't mock it. For example, searching for escalate shows the built-in escalate_conversation tool with the labels Writes data and Simulated success. The note at the bottom reminds you that these are the tools of the published Atlas, the version simulations run against.
Add tool search for escalate showing the Built-in tool escalate_conversation with its description and the labels Writes data and Simulated success, and the note These are the tools of the published Atlas, the version simulations run against

The selected tool's card shows its type (Custom API, GET), its description and its Inputs (the arguments the AI fills in when it calls the tool; for get_project_status that is projectCode). You can add several tools to one set; select a tool in the list on the left to edit its cases.

If a tool is later removed from the published agent, the set shows Tool not found in the published agent. Use Re-bind to… to move its cases to another tool.


Step 3: Add a case with conditions

  1. Click Add case. Give it a label so you recognize it later: KG-2041 is on hold.
  2. Under When all of these match, click Add condition. Choose the argument projectCode, the comparison is, and type KG-2041. The field shows the argument's description from the API ("Kirana project code in the form KG-0000, for example KG-2041. Use upper case.") to help you type a valid value.
  3. Add more conditions if needed. The case only answers when every condition holds. Arguments you don't list can have any value.
Case 1 labelled KG-2041 is on hold with the condition projectCode is KG-2041 and the argument's description below the value, Add condition, Respond with 200 OK in JSON mode with the Success and Error templates, Suggest, Use a real response and Format buttons, a JSON body with projectCode KG-2041, name Surabaya warehouse expansion, status On hold, percentComplete 62 and approval stage CFO with nextApprover null, and the collapsed Advanced, Match raw arguments section

The comparisons you can choose depend on the argument's type:

Argument typeComparisons
Text (also lists, objects and unknown types)is, is not, contains, starts with, ends with, matches pattern, is one of, is empty, is not empty
Number=, ≠, <, ≤, >, ≥, is between (inclusive)
Yes/nois true, is false
Any typeis present, is missing

Tips:

  • Text comparisons ignore upper and lower case unless you switch on Aa (match case) on the condition. So kg-2041 also matches this case.
  • is one of takes a comma-separated list; is between takes a minimum and a maximum.
  • matches pattern uses a regular expression.
  • A case with no conditions matches every call. Put it last, because cases are checked from top to bottom and a catch-all would hide the cases below it.
  • For unusual inputs, open Advanced — Match raw arguments and paste a piece of JSON the call's arguments must contain. It is checked in addition to the conditions.

Step 4: Write the response

Under Respond with, write what the tool returns for this case. For Atlas, keep the status 200 OK, choose JSON and paste:

{
  "projectCode": "KG-2041",
  "name": "Surabaya warehouse expansion",
  "status": "On hold",
  "percentComplete": 62,
  "approval": {
    "stage": "CFO",
    "nextApprover": null
  },
  "latestUpdate": "Paused by the CFO until the revised steel quotation is approved."
}

The editor adapts to the tool:

  • For a Custom API, choose the HTTP status in the field next to Respond with (default 200 OK). Error codes in the 5xx range reach the agent as an empty result, just like a real failing API.
  • Switch between JSON and Text for the body. Some tools also offer a Form that fits the tool's output (for example rows and columns for a table query), with View as JSON for the raw body.
  • Success and Error open ready-made templates, such as an empty list, "Not found (404)", "Unauthorized (401)", "Rate limited (429)", "Service down or timed out" for a Custom API, or "Query fails" and "No rows found" for a table query.
  • For an MCP tool, choose Content or MCP error. For another agent, write the reply text.
  • Suggest lets AI draft a response for the case. Format tidies the JSON.
  • Use a real response calls the real tool once so you can copy its shape. It is only available for tools that only read data, such as a Custom API that uses GET; for other tools it is locked because calling them could create real data.

Response bodies can be up to 64 KB.


Step 5: Decide what happens to every other call

Below the cases, the Otherwise (every other call) box decides what the tool answers when no case matches. For Atlas, every other project code should look unknown:

  1. Click Error and pick the not-found template, or set the status to 404 Not Found yourself.
  2. Make sure the body is {"error":"Not found"} in JSON mode.
  3. Open Advanced and keep Respond with a default.
Otherwise (every other call) box with Respond with 404 Not Found, JSON mode, the body error Not found, and the expanded Advanced options Respond with a default (selected) and Keep looking, check the next mock set, then the tool's default policy

The two options under Advanced:

  • Respond with a default: the call gets the response you write in this box (here: 404 with {"error":"Not found"}).
  • Keep looking: the call moves on to the next mock set, and if none answers, to the tool's default from the table in Why use mocks. In the tool list such tools are marked "Keeps looking".

Click Save. The set now appears on the Tool Mocks page with its description, 1 tool · 1 case, the tool chip get_project_status, and how many conversations use it.

Tool Mocks page with New Mock Set, Show Filters and Sort By Updated Date Descending, and one mock set card: Projects API: KG-2041 on hold, its description, 1 tool · 1 case, the chip get_project_status, and Used in 0 conversations

Step 6: Attach the mock set to a conversation simulation

  1. Open Simulation → Scenarios and create a conversation simulation with two steps. See Design Scenarios for the details.
    • Step 1, user message: What is the status of project KG-2041?
    • Step 2, user message: And project KG-9999?
  2. Add the expected responses, then click Suggest All Criteria to let AI write the evaluation criteria for every step. Review them and remove any you don't want.
  3. In the Tool mocks card, click Add mock set:
    • From library… attaches a shared set. Choose Projects API: KG-2041 on hold.
    • Create new makes a Private set that belongs only to this conversation.
  4. Click Save. The CMS asks for a Conversation Name and a Folder. Enter Project status: KG-2041 on hold, unknown code, keep the folder Default, and click Continue.
Tool mocks card on a conversation simulation: Mock sets attached (1), used by every step, with Projects API: KG-2041 on hold (1 tool · 1 case, get_project_status, Library chip, Edit link and menu), the Add mock set button, and Date & time the agent sees with the Real time switch off

Things to know:

  • Sets attached here are used by every step. Drag the rows to change their order: the first set that answers a call wins.
  • Each step also has its own Tool mocks (n) row with Add step mock set. A step's own sets are checked before the conversation's sets, so you can change one tool's answer for a single step (for example "the first lookup finds nothing, the second one finds the project").
  • Date & time the agent sees: by default the agent sees the real time. Turn the switch on to fix the date, time and time zone for this simulation. Use it when tool arguments depend on dates ("tomorrow"), so the conditions keep matching on every run.
  • In the row's ⋮ menu, Make a private copy (on a library set) gives this conversation its own copy that you can change without affecting other conversations, and Save to library (on a private set) shares it with the rest of the agent's simulations.

Step 7: Run the simulation

Click Run on the conversation. If the run could reach tools that are blocked in simulations and have no mock, an Attention dialog lists them first. For Atlas it says the run "will hit 3 blocked tools, which will return a policy error instead of actually running": Ledger (the agent from Work With Other Agents) and resolve-library-id and query-docs (the tools from Connect an MCP Server).

Attention dialog: Running Project status: KG-2041 on hold, unknown code will hit 3 blocked tools, which will return a policy error instead of actually running: Ledger, resolve-library-id, query-docs. Run anyway? with the buttons Run anyway and Cancel

These questions are about project status, so Atlas should not need any of those tools. Click Run anyway. If a scenario does depend on a blocked tool, click Cancel and add a mock for it first.


Check the result

  1. When the run is done, open it from the Results tab (see Run and Track). The conversation shows Completed, the folder Default, 2/2 Steps completed, the duration (here 14 s), and 5/6 Matched.
Completed conversation row Project status: KG-2041 on hold, unknown code in folder Default with 2/2 Steps completed, 14s, the Mocks used in this run link, and 5/6 Matched
  1. Click Mocks used in this run to see the exact mock sets the run used, frozen at the time of the run, and the simulated clock if you set one.
  2. Expand Step #1 and open Tool calls. The call custom:get_project_status with the arguments {"projectCode":"KG-2041"} shows the chips Mocked and Conversation. The line underneath names the case 'KG-2041 is on hold', the mock set Projects API: KG-2041 on hold and the status 200.
Tool calls (1) with the chip Mocked 1, listed in the order the agent called them: #1 custom:get_project_status with the chips Mocked and Conversation, the arguments projectCode KG-2041, the line Case KG-2041 is on hold · Projects API: KG-2041 on hold → 200, and the Save as case button

Each call shows an outcome chip and where its answer came from:

OutcomeWhat happened
MockedA case matched. The line underneath names the case and the mock set, plus the status code. The second chip says whether the set came from the Step or the Conversation.
DefaultNo case matched, and the tool's Otherwise default answered. In Step #2, the call for KG-9999 is answered this way with the 404.
SimulatedNo mock answered; the tool's built-in simulated success was used.
LiveThe real tool ran. These rows carry a warning that they may contain real data.
BlockedNo call was made. Use Mock this call to add a mock for it.
InternalAn internal tool that always runs.

Expand a call to see the full Arguments and Response. If the tool has a Response Prompt, the row notes that it was applied on top of the mocked response, just as in production. On a Mocked or Live call, Save as case turns the call into a new case (in a private set for this step, for the whole conversation, or in an existing set), which is the quickest way to build mocks from real behavior.

  1. Look at the step's answer and criteria. In Step #1, Atlas reports the status On hold at approval stage CFO, 62% complete, and the latest update from the mock. Three of the four criteria match. The one that fails is Identifies KG-2041 as the Surabaya warehouse expansion project: the evaluation notes that the answer does not mention KG-2041 or name the project.
Step #1 with 3/4 Matched: the user message What is the status of project KG-2041?, the Expected Response and the AI Agent Response (Status On hold, approval stage CFO; Progress 62% complete; Budget not provided in the project status; Latest update Paused by the CFO until the revised steel quotation is approved) with the matching parts highlighted, and the Evaluation Criteria: Identifies KG-2041 as the Surabaya warehouse expansion project (not matched, with the reason), and three matched criteria for on hold at the CFO stage, 62% complete, and paused until the revised steel quotation is approved

This is exactly what simulations are for. The mocked data was correct, so the failure points at the agent, not at the data. Atlas's Response Prompt tells it to start with the status and the approval stage, so it never says which project it is talking about. A reader with three projects open could mix them up. You can fix it in the Response Prompt of get_project_status (for example, "Start with the project code and name, then the status and the current approval stage..."), publish, and run the simulation again until it shows 6/6 Matched. Notice also the line "Budget: Not provided in the project status": the mock has no budget fields, and Atlas says so instead of inventing numbers.

  1. Expand Step #2. The call for KG-9999 matches no case, so the Otherwise default answers with 404, and Atlas says the code is unknown and asks the user to check it, as the API's Rules tell it to. Both criteria of this step match.

If the result is not what you expect:

  • The call shows Blocked instead of Mocked. The mock set is not attached to this conversation or step, or it mocks a different tool. Check the Tool mocks card and the tool name.
  • The call shows Default for KG-2041. The condition does not match the argument the AI sent. Expand the call, compare the Arguments with the condition, and check whether Aa (match case) is on.
  • The tool is missing from Add tool. Publish the agent after adding or renaming the tool.

Limits and good practice

  • Mocks only apply to conversation simulations. Preview, the published agent and real channels always call the real tools.
  • A mock set holds up to 50 tools, each tool up to 50 cases, each case up to 20 conditions.
  • Web search and web scraping cannot be mocked; they run live in simulations.
  • Mocks follow the published agent: publish after adding or renaming a tool, then update your mock sets.
  • Keep one purpose per mock set ("happy path", "API down", "project on hold") and combine sets per scenario, rather than one huge set.
  • Always test at least one error path (Error templates) so you know how your agent answers when a service fails. The 404 for KG-9999 above is one.

For the full list of fields on these screens, see the Help pages Mocks, Scenarios and Results.


Next steps