AI-Ready Unit Tests: How to Mock LLM Responses in Apex 🤖🧪
By Shruthi MN | April 9, 2026 Reading Time: 10 minutes
In the era of Agentforce, our Apex code is no longer just calculating numbers; it’s interacting with Large Language Models (LLMs). But here is the problem: LLMs are non-deterministic. If you run a test today, the AI might return "Hello." Tomorrow, it might return "Greetings."
Your deployment will fail, your CI/CD will break, and your "Clean Core" will crumble. To build AI-Ready Unit Tests, you must master the art of Mocking the Reasoning Engine.
The Architecture of an AI Mock 🏗️
When your Apex code calls an LLM (via the ConnectApi or an external service), you cannot make a real call during a test. You need to intercept that call and provide a "Static AI Response."
The 3 Components of an AI-Ready Test:
The Service Wrapper: Don't call the LLM directly in your logic. Wrap it in a service class.
The Mock Interface: Use
HttpCalloutMockor the newSystem.AI.MockResponse(2026 Beta).The Assertion: Test the structure of the AI response, not just the text.
🏗️ The 10/10 Implementation: Mocking Agentic Output
Here is the pattern for testing an Apex Action that is triggered by an Agentforce Agent.
The Code Pattern:
@IsTest
global class AgenticActionMock implements HttpCalloutMock {
global HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
// Providing a deterministic "AI" response for the test
res.setBody('{"answer": "Verified", "confidence": 0.98}');
res.setStatusCode(200);
return res;
}
}
@IsTest
static void testAgentAction() {
Test.setMock(HttpCalloutMock.class, new AgenticActionMock());
Test.startTest();
// Your logic that calls the LLM
String result = MyAIController.askAgent('Is this account valid?');
Test.stopTest();
Assert.areEqual('Verified', result, 'The AI Mock should return a deterministic answer.');
}
Day 2: The "Death of the Getter" & AI Testing! 🎯
I have officially launched Day 2 of our 15-Day Agentforce & LWC Challenge on LinkedIn! Today, we are discussing how The Death of the Getter makes our LWCs easier to test.
The Challenge: If an LWC uses a Template Expression to display an AI response, how do you verify the UI output in a Jest Test? I’ve posted the "Jest-to-AI" solution on LinkedIn—go solve it!
The Final 5 Countdown: We are officially JUST 5 HUBS AWAY from our 100-subscriber milestone on YouTube! 🚀
The moment we hit 100, I’m releasing my "AI Test Factory"—a class that generates random but structured mock data for any Agentforce test.
👉 SOLVE THE JEST CHALLENGE: [https://www.linkedin.com/posts/shruthi-m-n-898a59330_salesforce-lwc-cleancode-share-7448015180510351360-fENp?utm_source=share&utm_medium=member_desktop&rcm=ACoAAFNzDrQBUm4e9s1OgNy0ESF9RXmSaHOfvMM]
📺 BE HUB #100: [
🔒 Content Integrity & Originality Statement All technical solutions, code snippets, and architectural patterns shared on Salesforce CodeForce Chronicles are 100% original, authored by Shruthi M N. This content is derived from real-world project experience and extensive research within the Salesforce ecosystem. We do not use "scraped" content or unauthorized copies.
Code Policy: You are free to use this code in your own Salesforce orgs! However, redistribution of this written content on other blogs without prior written consent is strictly prohibited.