AI-Ready Unit Tests: How to Mock LLM Responses in Apex 🤖🧪


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:

  1. The Service Wrapper: Don't call the LLM directly in your logic. Wrap it in a service class.

  2. The Mock Interface: Use HttpCalloutMock or the new System.AI.MockResponse (2026 Beta).

  3. 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:

JavaScript
@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: [https://www.youtube.com/@CodeForceChronicles]

🔒 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.

Post a Comment

Previous Post Next Post